Initial commit
This commit is contained in:
commit
41868ff6c7
7 changed files with 349 additions and 0 deletions
35
.vscode/settings.json
vendored
Normal file
35
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"sqltools.connections": [
|
||||||
|
{
|
||||||
|
"mssqlOptions": {
|
||||||
|
"appName": "SQLTools",
|
||||||
|
"useUTC": true,
|
||||||
|
"encrypt": true
|
||||||
|
},
|
||||||
|
"previewLimit": 50,
|
||||||
|
"server": "127.0.0.1",
|
||||||
|
"port": 1433,
|
||||||
|
"driver": "MSSQL",
|
||||||
|
"name": "server (AP)",
|
||||||
|
"database": "AP",
|
||||||
|
"username": "ben",
|
||||||
|
"connectionTimeout": 3,
|
||||||
|
"password": "pass"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"mssqlOptions": {
|
||||||
|
"appName": "SQLTools",
|
||||||
|
"useUTC": true,
|
||||||
|
"encrypt": true
|
||||||
|
},
|
||||||
|
"previewLimit": 50,
|
||||||
|
"server": "localhost",
|
||||||
|
"port": 1433,
|
||||||
|
"driver": "MSSQL",
|
||||||
|
"name": "server (WideWorldImporters)",
|
||||||
|
"database": "WideWorldImporters",
|
||||||
|
"username": "ben",
|
||||||
|
"password": "pass"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
95
instructions/database-programming/lab-1.md
Normal file
95
instructions/database-programming/lab-1.md
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
# Lab 1
|
||||||
|
|
||||||
|
This lab has you practice simple queries against tables with filtering and ordering. Write the SQL queries that properly answer each scenario.
|
||||||
|
|
||||||
|
For each scenario include the following in your answer:
|
||||||
|
|
||||||
|
- The SQL query (properly formatted)
|
||||||
|
- The number of rows returned by the query
|
||||||
|
|
||||||
|
*Note: DO NOT hard code any primary key IDs in your queries.*
|
||||||
|
|
||||||
|
This lab uses the `WideWorldImporters` database.
|
||||||
|
|
||||||
|
## Scenario 1
|
||||||
|
|
||||||
|
Select the `SupplierName`, `WebsiteURL`, `DeliveryAddressLine1`, `DeliveryAddressLine2` and `DeliveryPostalCode` columns from the `Purchasing.Suppliers` table.
|
||||||
|
|
||||||
|
Rows: 13
|
||||||
|
|
||||||
|
## Scenario 2
|
||||||
|
|
||||||
|
Select the `StateProvinceName`, `SalesTerritory`, and `CountryID` from the `Application.StateProvinces` table.
|
||||||
|
Include only the rows where `SalesTerritory` is `Southeast`.
|
||||||
|
Order the rows by `StateProvinceName`.
|
||||||
|
|
||||||
|
Rows: 12
|
||||||
|
|
||||||
|
## Scenario 3
|
||||||
|
|
||||||
|
Select the `CustomerID`, `TransactionDate` and `TransactionAmount` from the `Sales.CustomerTransactions` table.
|
||||||
|
Include only the rows where `TransactionAmount` is less than zero and `TransactionDate` is in the year 2015.
|
||||||
|
Order the rows by `TransactionDate` descending and then by `TransactionAmount` ascending.
|
||||||
|
|
||||||
|
Rows: 8635
|
||||||
|
|
||||||
|
## Scenario 4
|
||||||
|
|
||||||
|
Select the `CountryName`, `Continent`, `Region`, `Subregion` from the `Application.Countries` table.
|
||||||
|
Include only the rows where `LatestRecordedPopulation` is greater than 1 million people and `Continent` is not `Oceania`.
|
||||||
|
Order the rows by `CountryName`, `Continent`, `Region` and then `Subregion`.
|
||||||
|
|
||||||
|
Rows: 147
|
||||||
|
|
||||||
|
## Scenario 5
|
||||||
|
|
||||||
|
Select the `StockItemName`, `RecommendedRetailPrice` and `Tags` from the `Warehouse.StockItems` table.
|
||||||
|
Include only the rows where `IsChillerStock` is true and `StockItemName` begins with `USB`.
|
||||||
|
Order the rows by `StockItemName`.
|
||||||
|
Only return the first 10 rows.
|
||||||
|
|
||||||
|
Rows: 10
|
||||||
|
|
||||||
|
## Scenario 6
|
||||||
|
|
||||||
|
Select the `InvoiceId`, `InvoiceDate` and `CustomerName` from the `Sales.Invoices` and `Sales.Customers` tables.
|
||||||
|
Include only the invoices from `1/1/2016' to '3/1/2016' and customers that do not have`Toys` in the name.
|
||||||
|
Order the rows by `CustomerName` and then by `InvoiceDate`.
|
||||||
|
|
||||||
|
Rows: 1382
|
||||||
|
|
||||||
|
*Note: Return `CustomerName`, not `CustomerId`.
|
||||||
|
|
||||||
|
## Scenario 7*
|
||||||
|
|
||||||
|
Select the `ColorName` columns from the `Warehouse.Colors` table that are not being used in the `Warehouse.StockItems` table.
|
||||||
|
The `Warehouse.StockItems.ColorId` column contains the `Warehouse.Colors.ColorId` value.
|
||||||
|
Order by `ColorName`.
|
||||||
|
|
||||||
|
Rows: 29
|
||||||
|
|
||||||
|
## Scenario 8
|
||||||
|
|
||||||
|
Select the `CityName`, `StateProvinceName` and `StateProvinceCode` from the `Application.Cities` table.
|
||||||
|
Include only the cities that begin with the letter `A` from states that are in the `Southeast` sales territory.
|
||||||
|
Order the rows by `StateProvinceName` descending and then by `CityName`.
|
||||||
|
|
||||||
|
Rows: 376
|
||||||
|
|
||||||
|
## Scenario 9
|
||||||
|
|
||||||
|
Select the `CustomerId` (as `Id`) and `CustomerName` (as `Name`) columns from the `Sales.Customers` table combined with the `SupplierId` and `SupplierName` columns from the `Purchasing.Suppliers` table.
|
||||||
|
Include a `Type` column that is set to `Customer` for customer rows and `Supplier` for supplier rows.
|
||||||
|
Order the resulting data by the type and then by customer/supplier name.
|
||||||
|
|
||||||
|
Rows: 676
|
||||||
|
|
||||||
|
*Note: The resultset will have only 3 columns (`Type`, `Id` and `Name`).*
|
||||||
|
|
||||||
|
## Scenario 10
|
||||||
|
|
||||||
|
Select the `CityName`, `StateProvinceName`, `CountryName` and `SalesTerritory` from the `Application.Cities`, `Application.StateOrProvinces` and `Application.Countries` tables.
|
||||||
|
Include only the rows that are for the `SalesTerritory` with values of `Southeast` or `Southwest`.
|
||||||
|
Order the rows by `StateProvinceName` and then by `CityName`.
|
||||||
|
|
||||||
|
Rows: 13341
|
105
notes/database-prog/sql-scripts/2024-01-24.sql
Normal file
105
notes/database-prog/sql-scripts/2024-01-24.sql
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
-- T-SQL
|
||||||
|
-- Keywords - UPPERCASE, Tables/Columns/etc - PascalCase, everything else - doesn't matter
|
||||||
|
-- Comments with double-hyphen
|
||||||
|
USE AP
|
||||||
|
GO
|
||||||
|
|
||||||
|
SELECT VendorID, VendorName, LEFT(VendorName, 10) VendorShortName,
|
||||||
|
VendorAddress1, VendorAddress2, VendorCity
|
||||||
|
FROM Vendors
|
||||||
|
|
||||||
|
-- batch run everything before it
|
||||||
|
-- GO 2
|
||||||
|
|
||||||
|
SELECT *
|
||||||
|
FROM Terms
|
||||||
|
|
||||||
|
SELECT InvoiceID, InvoiceNumber, InvoiceTotal, PaymentTotal, CreditTotal,
|
||||||
|
CASE PaymentTotal
|
||||||
|
WHEN InvoiceTotal THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END IsPaidFull
|
||||||
|
FROM Invoices
|
||||||
|
|
||||||
|
-- includes credit
|
||||||
|
SELECT InvoiceID, InvoiceNumber, InvoiceTotal, PaymentTotal, CreditTotal, InvoiceTotal - CreditTotal PaidTotal,
|
||||||
|
CASE PaymentTotal
|
||||||
|
WHEN InvoiceTotal - CreditTotal THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END IsPaidFull
|
||||||
|
FROM Invoices
|
||||||
|
|
||||||
|
-- better
|
||||||
|
SELECT TOP 500
|
||||||
|
InvoiceID, InvoiceNumber, InvoiceTotal, PaymentTotal, CreditTotal, InvoiceTotal - CreditTotal PaidTotal,
|
||||||
|
CASE WHEN PaymentTotal = InvoiceTotal - CreditTotal THEN 1
|
||||||
|
ELSE 0
|
||||||
|
END IsPaidFull
|
||||||
|
FROM Invoices
|
||||||
|
ORDER BY VendorID, InvoiceDueDate
|
||||||
|
|
||||||
|
SELECT TOP 50 InvoiceID, VendorID FROM Invoices
|
||||||
|
ORDER BY VendorID
|
||||||
|
|
||||||
|
-- 2024-01-29
|
||||||
|
|
||||||
|
-- paging
|
||||||
|
-- skip first offset rows, return next fetch rows
|
||||||
|
SELECT InvoiceID, InvoiceNumber, InvoiceDueDate
|
||||||
|
FROM Invoices
|
||||||
|
ORDER BY InvoiceDueDate
|
||||||
|
OFFSET 110 ROWS
|
||||||
|
FETCH NEXT 10 ROWS ONLY
|
||||||
|
|
||||||
|
-- Filtering
|
||||||
|
-- just return what you need, instead of filtering in the application
|
||||||
|
SELECT InvoiceID, VendorID, InvoiceDueDate, InvoiceTotal
|
||||||
|
FROM Invoices
|
||||||
|
-- Note that equality is a single equals sign
|
||||||
|
WHERE InvoiceTotal >= 1000 OR VendorID = 110
|
||||||
|
ORDER BY VendorID, InvoiceDueDate
|
||||||
|
|
||||||
|
SELECT VendorID, VendorName, VendorCity, VendorState
|
||||||
|
FROM Vendors
|
||||||
|
-- Note strings use apostrephes, not quotation marks
|
||||||
|
-- Keep in mind *there is no short-circuit evaluation*, so this will run every single thing and it's messy and slow
|
||||||
|
--WHERE VendorState = 'CA' OR VendorState = 'AZ' OR VendorState = 'OH' OR VendorState = 'NY'
|
||||||
|
-- Instead, use IN
|
||||||
|
WHERE VendorState IN ('CA', 'AZ', 'OH', 'NY')
|
||||||
|
ORDER BY VendorName
|
||||||
|
|
||||||
|
SELECT InvoiceID, InvoiceNumber, InvoiceTotal
|
||||||
|
FROM Invoices
|
||||||
|
--WHERE InvoiceTotal >= 100 AND InvoiceTotal <= 500
|
||||||
|
--less typing and more optimized
|
||||||
|
--keep in mind it's an inclusive between, not exclusive
|
||||||
|
WHERE InvoiceTotal BETWEEN 100 AND 500
|
||||||
|
ORDER BY InvoiceDueDate
|
||||||
|
|
||||||
|
-- Haven't paid
|
||||||
|
-- if either VendorAddress1 or VendorAddress2 are `NULL`, then the concatenation will just be `NULL`
|
||||||
|
-- so this filters out all the nulls
|
||||||
|
-- (note that the VendorAddress1 one isn't actually needed because the dataset doesn't contain any that has VendorAddress1 as `NULL` but VendorAddress2 defined)
|
||||||
|
SELECT VendorID, VendorName, VendorAddress1, VendorAddress2, VendorAddress1 + ' ' + VendorAddress2 FROM Vendors
|
||||||
|
WHERE VendorAddress1 IS NOT NULL AND VendorAddress2 IS NOT NULL
|
||||||
|
-- or ISNULL to just return a string instead of NULL
|
||||||
|
SELECT VendorID, VendorName, VendorAddress1, VendorAddress2, ISNULL(VendorAddress1, '') + ' ' + ISNULL(VendorAddress2, '') FROM Vendors
|
||||||
|
-- or COALESCE
|
||||||
|
SELECT VendorID, VendorName, VendorAddress1, VendorAddress2, COALESCE(VendorAddress1, '') + ' ' + COALESCE(VendorAddress2, '') FROM Vendors
|
||||||
|
|
||||||
|
-- All vendors with PO Boxes
|
||||||
|
SELECT VendorID, VendorName, VendorAddress1, VendorAddress2 FROM Vendors
|
||||||
|
-- '%PO BOX%' is equivalent to '.*PO BOX.*' in regex
|
||||||
|
WHERE VendorAddress1 LIKE '%PO BOX%' OR VendorAddress2 LIKE '%PO BOX%'
|
||||||
|
|
||||||
|
-- Get current date
|
||||||
|
--SELECT GETDATE(), GET UTCDATE()
|
||||||
|
-- Get all invoices for January
|
||||||
|
SELECT InvoiceId, InvoiceNumber, InvoiceDueDate FROM Invoices
|
||||||
|
WHERE MONTH(InvoiceDueDate) = 1
|
||||||
|
--WHERE DAY(InvoiceDueDate) IN (30, 31)
|
||||||
|
-- Get all invoices for 2019
|
||||||
|
--WHERE YEAR(InvoiceDeDate) = 2019
|
||||||
|
-- More efficient version, also more flexible, but longer
|
||||||
|
--WHERE InvoiceDueDate BETWEEN '1/1/2019' AND '12/31/2019'
|
||||||
|
|
19
notes/database-prog/sql-scripts/2024-01-31.sql
Normal file
19
notes/database-prog/sql-scripts/2024-01-31.sql
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
-- #### Start of class stuff ####
|
||||||
|
|
||||||
|
-- Get the InvoiceId, InvoiceTotal, and InvoiceDueDate for all invoices for vendor 110
|
||||||
|
SELECT InvoiceId, InvoiceTotal, InvoiceDueDate
|
||||||
|
FROM Invoices
|
||||||
|
WHERE VendorID = 110
|
||||||
|
|
||||||
|
-- Get the latest 10 invoices for vendor 123: InvoiceId, InvoiceDueDate, InvoiceTotal
|
||||||
|
SELECT TOP 10 InvoiceId, InvoiceTotal, InvoiceDueDate
|
||||||
|
FROM Invoices
|
||||||
|
WHERE VendorID = 123
|
||||||
|
ORDER BY InvoiceDueDate DESC
|
||||||
|
|
||||||
|
-- Get the InvoiceId, VendorId, InvoiceDueDate, and InvoiceTotal for all invoices due between 1/1/2020 and 1/31/2020
|
||||||
|
SELECT InvoiceId, VendorId, InvoiceDueDate, InvoiceTotal
|
||||||
|
FROM Invoices
|
||||||
|
WHERE InvoiceDueDate BETWEEN '1/1/2020' AND '1/31/2020'
|
||||||
|
|
||||||
|
-- ######################################################################## --
|
44
notes/database-prog/syntax.md
Normal file
44
notes/database-prog/syntax.md
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# SQL Syntax
|
||||||
|
|
||||||
|
## Keywords
|
||||||
|
|
||||||
|
`|`: Use for designating different things that can be used as arguments for the keywords
|
||||||
|
`( )`: Optional keywords
|
||||||
|
`[ ]`: Used for values, like integers, or column or table names.
|
||||||
|
|
||||||
|
| Keyword | Explanation | Example |
|
||||||
|
| ------- | ----------- | ------- |
|
||||||
|
| `USE` | Specify the database to be used | `USE WideWorldImporters` |
|
||||||
|
| `SELECT {ColumnID \| *}` | selects the column to return (or can use wildcard `*`) | `SELECT ProductID FROM Products` |
|
||||||
|
| `FROM` | specify the thing to be selected from |
|
||||||
|
| `GO {count}` | Runs everything before it `count` times minus 1 | `GO 5` (runs everything before it 4 more times) |
|
||||||
|
| `TOP {n} (PERCENT - optional)` | Returns the top *n* (or *n*%) results - must be an integer . Order is undefined, but in most implementations is listed in the order they were inserted - NOT guaranteed behavior, just how most implementations use it. | `SELECT TOP 10 PERCENT VendorName FROM Vendors` |
|
||||||
|
| `ORDER BY {column1, column2 (1 required, can use infinitely many)}` | Orders by some column (alphanumerically sorted, letters first); `TOP` is useless without this | `SELECT TOP 50 InvoiceID, VendorID FROM Invoices ORDER BY VendorID` |
|
||||||
|
| `DISTINCT` | Goes before the column names (and before TOP in MS SQL server, at least); removes rows with duplicate values | `SELECT DISTINCT VendorName FROM Invoices` |
|
||||||
|
|
||||||
|
<!-- Needs to be redone into more detailed sub-headings -->
|
||||||
|
|
||||||
|
## `CASE`/`WHEN`/`THEN`/`ELSE`/`END`
|
||||||
|
|
||||||
|
## Other syntax
|
||||||
|
|
||||||
|
- Brackets `[ ]`: Delineates that something is a table, usually not needed but allows for stuff like using keywords as table names.
|
||||||
|
|
||||||
|
## Other notes
|
||||||
|
|
||||||
|
- `SELECT * FROM Table`: Shouldn't be used normally, only in learning or if you're not sure what you need yet.
|
||||||
|
- Bad because: it's requests every column of data in the table, and that's rarely needed, wasting time and resources.
|
||||||
|
- Most database systems will just skip all qury optimizations if you do this, wasting even more time and resources.
|
||||||
|
- Column ordering is undefined - the columns could be returned in any random order.
|
||||||
|
- Should usually do one keyword per line, except for simple stuff like `SELECT ColumnID FROM Table`
|
||||||
|
- Column aliases: Useful for:
|
||||||
|
- Multi-table connections and for "renaming" columns
|
||||||
|
- Making it more convenient to use (e.g. `Person` -> `Name` as an alias of `Person` -> `PersonName`)
|
||||||
|
- To name an unnamed column (e.g. `SELECT LEFT(VendorName, 10) VendorShortName FROM Vendors`)
|
||||||
|
|
||||||
|
## No
|
||||||
|
|
||||||
|
Don't:
|
||||||
|
|
||||||
|
- Put spaces in a table's name (why would you???)
|
||||||
|
- Use `SELECT * FROM Table`
|
0
notes/fund-prog-3/2024-01-24.md
Normal file
0
notes/fund-prog-3/2024-01-24.md
Normal file
51
notes/fund-prog-3/some-sorts-2024-01-31.md
Normal file
51
notes/fund-prog-3/some-sorts-2024-01-31.md
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# Some sorts
|
||||||
|
|
||||||
|
In pseudocode, but python syntax highlighting fits decently so that's what I'm using.
|
||||||
|
|
||||||
|
## Insertion sort (for shell sort)
|
||||||
|
|
||||||
|
```py
|
||||||
|
InsertionSortForShell(array, start, gap)
|
||||||
|
for i = start + gap to len(array) - 1 # inclusive
|
||||||
|
j = i
|
||||||
|
while (j - gap >= start) and (array[j] < array[j - gap])
|
||||||
|
swap(array[j], array[j - gap])
|
||||||
|
j = j - gap
|
||||||
|
```
|
||||||
|
|
||||||
|
## Shell sort
|
||||||
|
|
||||||
|
```py
|
||||||
|
ShellSort(array, gapList)
|
||||||
|
for gap in gapList
|
||||||
|
for i = = 0 to gap - 1
|
||||||
|
InsertionSortForShell(array, i, gap)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hibbard
|
||||||
|
|
||||||
|
2<sup>k</sup> - 1 where k is 1 to p where └ k<sup>p</sup> ┐ = N
|
||||||
|
|
||||||
|
## Pratt
|
||||||
|
|
||||||
|
For a Z-tuples for (0, 0) -> (k, k) create all the cartesian pairs
|
||||||
|
|
||||||
|
```txt
|
||||||
|
(0, 0), (0, 1), (0, 2), ..., (0, k)
|
||||||
|
(1, 0), (1, 1), (1, 2), ..., (1, k)
|
||||||
|
(2, 0), (2, 1), (2, 2), ..., (2, k)
|
||||||
|
...
|
||||||
|
(k, 0), (k, 1), (k, 2), ..., (k, k)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Naive gap values
|
||||||
|
|
||||||
|
N/2<sup>k</sup>, k = 1 to p where N/2<sup>p</sup> => 1
|
||||||
|
|
||||||
|
```py
|
||||||
|
for i, j in S
|
||||||
|
value = 2<sup>i</sup> * 3<sup>j</sup>
|
||||||
|
gapList.append(value)
|
||||||
|
sort(gapList)
|
||||||
|
gapValues[0 ... N]
|
||||||
|
```
|
Loading…
Reference in a new issue