commit 41868ff6c702363bac74703944c211ce44b794c1 Author: askiiart Date: Wed Jan 31 20:20:15 2024 -0600 Initial commit diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6581664 --- /dev/null +++ b/.vscode/settings.json @@ -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" + } + ] +} \ No newline at end of file diff --git a/instructions/database-programming/lab-1.md b/instructions/database-programming/lab-1.md new file mode 100644 index 0000000..24dfac7 --- /dev/null +++ b/instructions/database-programming/lab-1.md @@ -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 diff --git a/notes/database-prog/sql-scripts/2024-01-24.sql b/notes/database-prog/sql-scripts/2024-01-24.sql new file mode 100644 index 0000000..20e99bf --- /dev/null +++ b/notes/database-prog/sql-scripts/2024-01-24.sql @@ -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' + diff --git a/notes/database-prog/sql-scripts/2024-01-31.sql b/notes/database-prog/sql-scripts/2024-01-31.sql new file mode 100644 index 0000000..957bf9b --- /dev/null +++ b/notes/database-prog/sql-scripts/2024-01-31.sql @@ -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' + +-- ######################################################################## -- \ No newline at end of file diff --git a/notes/database-prog/syntax.md b/notes/database-prog/syntax.md new file mode 100644 index 0000000..6776735 --- /dev/null +++ b/notes/database-prog/syntax.md @@ -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` | + + + +## `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` diff --git a/notes/fund-prog-3/2024-01-24.md b/notes/fund-prog-3/2024-01-24.md new file mode 100644 index 0000000..e69de29 diff --git a/notes/fund-prog-3/some-sorts-2024-01-31.md b/notes/fund-prog-3/some-sorts-2024-01-31.md new file mode 100644 index 0000000..7b3a285 --- /dev/null +++ b/notes/fund-prog-3/some-sorts-2024-01-31.md @@ -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 + +2k - 1 where k is 1 to p where └ kp ┐ = 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/2k, k = 1 to p where N/2p => 1 + +```py +for i, j in S + value = 2i * 3j + gapList.append(value) + sort(gapList) + gapValues[0 ... N] +```