diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..1d793a1 --- /dev/null +++ b/.clang-format @@ -0,0 +1,9 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +ColumnLimit: 120 +BreakBeforeBraces: Custom +BraceWrapping: + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: true diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..3165371 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,33 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "/home/askiiart/Documents/compsci-notes-spring-2024/labs/cosc-2436/4.14/C++/output/main", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + } + + ], +} \ No newline at end of file diff --git a/labs/cosc-2436/4.14/C++/Node.h b/labs/cosc-2436/4.14/C++/Node.h deleted file mode 100644 index ccc63b4..0000000 --- a/labs/cosc-2436/4.14/C++/Node.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef NODE_H -#define NODE_H - -class Node { -protected: - double data; - Node* next; - Node* previous; - -public: - // Constructs this node with the specified numerical data value. The next - // and previous pointers are each assigned nullptr. - Node(double initialData) { - data = initialData; - next = nullptr; - previous = nullptr; - } - - // Constructs this node with the specified numerical data value, next - // pointer, and previous pointer. - Node(double initialData, Node* nextNode, Node* previousNode) { - data = initialData; - next = nextNode; - previous = previousNode; - } - - virtual ~Node() { - } - - // Returns this node's data. - virtual double GetData() { - return data; - } - - // Sets this node's data. - virtual void SetData(double newData) { - data = newData; - } - - // Gets this node's next pointer. - virtual Node* GetNext() { - return next; - } - - // Sets this node's next pointer. - virtual void SetNext(Node* newNext) { - next = newNext; - } - - // Gets this node's previous pointer. - virtual Node* GetPrevious() { - return previous; - } - - // Sets this node's previous pointer. - virtual void SetPrevious(Node* newPrevious) { - previous = newPrevious; - } -}; - -#endif diff --git a/labs/cosc-2436/4.14/C++/SortedNumberList.h b/labs/cosc-2436/4.14/C++/SortedNumberList.h deleted file mode 100644 index 783df73..0000000 --- a/labs/cosc-2436/4.14/C++/SortedNumberList.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef SORTEDNUMBERLIST_H -#define SORTEDNUMBERLIST_H -#include "Node.h" - -class SortedNumberList { -private: - // Optional: Add any desired private functions here - -public: - Node* head; - Node* tail; - - SortedNumberList() { - head = nullptr; - tail = nullptr; - } - - // Inserts the number into the list in the correct position such that the - // list remains sorted in ascending order. - void Insert(double number) { - // Your code here - } - - // Removes the node with the specified number value from the list. Returns - // true if the node is found and removed, false otherwise. - bool Remove(double number) { - // Your code here (remove placeholder line below) - return false; - } -}; - -#endif diff --git a/labs/cosc-2436/4.14/C++/main.cpp b/labs/cosc-2436/4.14/C++/main.cpp deleted file mode 100644 index 8cb527a..0000000 --- a/labs/cosc-2436/4.14/C++/main.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include -#include -#include -#include "Node.h" -#include "SortedNumberList.h" -using namespace std; - -void PrintList(SortedNumberList& list); -vector SpaceSplit(string source); - -int main(int argc, char *argv[]) { - // Read the line of input numbers - string inputLine; - getline(cin, inputLine); - - // Split on space character - vector terms = SpaceSplit(inputLine); - - // Insert each value and show the sorted list's contents after each insertion - SortedNumberList list; - for (auto term : terms) { - double number = stod(term); - cout << "List after inserting " << number << ": " << endl; - list.Insert(number); - PrintList(list); - } - - /* - // Read the input line with numbers to remove - getline(cin, inputLine); - terms = SpaceSplit(inputLine); - - // Remove each value - for (auto term : terms) { - double number = stod(term); - cout << "List after removing " << number << ": " << endl; - list.Remove(number); - PrintList(list); - } - */ - - return 0; -} - -// Prints the SortedNumberList's contents, in order from head to tail -void PrintList(SortedNumberList& list) { - Node* node = list.head; - while (node) { - cout << node->GetData() << " "; - node = node->GetNext(); - } - cout << endl; -} - -// Splits a string at each space character, adding each substring to the vector -vector SpaceSplit(string source) { - vector result; - size_t start = 0; - for (size_t i = 0; i < source.length(); i++) { - if (' ' == source[i]) { - result.push_back(source.substr(start, i - start)); - start = i + 1; - } - } - result.push_back(source.substr(start)); - return result; -} diff --git a/labs/cosc-2436/chapter-4/C++/Node.h b/labs/cosc-2436/chapter-4/C++/Node.h new file mode 100644 index 0000000..4a563e8 --- /dev/null +++ b/labs/cosc-2436/chapter-4/C++/Node.h @@ -0,0 +1,61 @@ +#ifndef NODE_H +#define NODE_H + +class Node { +protected: + double data; + Node* next; + Node* previous; + +public: + // Constructs this node with the specified numerical data value. The next + // and previous pointers are each assigned nullptr. + Node(double initialData) { + data = initialData; + next = nullptr; + previous = nullptr; + } + + // Constructs this node with the specified numerical data value, next + // pointer, and previous pointer. + Node(double initialData, Node* nextNode, Node* previousNode) { + data = initialData; + next = nextNode; + previous = previousNode; + } + + virtual ~Node() { + } + + // Returns this node's data. + virtual double GetData() { + return data; + } + + // Sets this node's data. + virtual void SetData(double newData) { + data = newData; + } + + // Gets this node's next pointer. + virtual Node* GetNext() { + return next; + } + + // Sets this node's next pointer. + virtual void SetNext(Node* newNext) { + next = newNext; + } + + // Gets this node's previous pointer. + virtual Node* GetPrevious() { + return previous; + } + + // Sets this node's previous pointer. + virtual void SetPrevious(Node* newPrevious) { + previous = newPrevious; + } +}; + +#endif diff --git a/labs/cosc-2436/4.14/C++/instructions.md b/labs/cosc-2436/chapter-4/C++/README.md similarity index 100% rename from labs/cosc-2436/4.14/C++/instructions.md rename to labs/cosc-2436/chapter-4/C++/README.md diff --git a/labs/cosc-2436/chapter-4/C++/SortedNumberList.h b/labs/cosc-2436/chapter-4/C++/SortedNumberList.h new file mode 100644 index 0000000..58b5758 --- /dev/null +++ b/labs/cosc-2436/chapter-4/C++/SortedNumberList.h @@ -0,0 +1,114 @@ +#ifndef SORTEDNUMBERLIST_H +#define SORTEDNUMBERLIST_H +#include "Node.h" + +class SortedNumberList { + private: + // Optional: Add any desired private functions here + + /* + These traverse the list up/down from startingNode and updates the head/tail + + Less efficient than just doing it in the functions based off the stuff there, but this is a bit easier on my brain + than dealing with edge cases there. Maybe the compiler can optimize it a bit, idk, I don't feel like digging + into the assembly (well, not right now) + + Note: These used to be one function, UpdateHeadAndTail(), but I've split UpdateHead() and UpdateTail() into two + different functions in order to minimize the performance hit. + */ + void UpdateHead(Node *startingNode) { + Node *currentNode = startingNode; + while (currentNode->GetPrevious() != nullptr) { + currentNode = currentNode->GetPrevious(); + } + head = currentNode; + } + + void UpdateTail(Node *startingNode) { + Node *currentNode = startingNode; + while (currentNode->GetNext() != nullptr) { + currentNode = currentNode->GetNext(); + } + tail = currentNode; + } + + public: + Node *head; + Node *tail; + + SortedNumberList() { + head = nullptr; + tail = nullptr; + } + + // Inserts the number into the list in the correct position such that the + // list remains sorted in ascending order. + void Insert(double number) { + if (head == nullptr) { // handle being a new list with no data in it + // if (false) { + head = new Node(number); + tail = head; + } + else { // actually do anything interesting + Node *currentNode = head; + while (true) { + // needs debugging, if less than head, replaces head, if more, throws SIGSEGV (Address boundary error) + if (currentNode->GetData() <= number && + (currentNode->GetNext() == nullptr || currentNode->GetNext()->GetData() <= number)) { + Node *newNode = new Node(number, currentNode->GetNext(), currentNode); + if (newNode->GetNext() != nullptr) { + currentNode->SetNext(newNode); + } + else { + head = newNode; + } + + if (newNode->GetNext() != nullptr) { + newNode->GetNext()->SetPrevious(newNode); + } + else { + tail = newNode; + } + // I split these into 2 different functions so they *could* be more efficient, + // not so they *would* be more efficient :P + // UpdateHead(newNode); + // UpdateTail(newNode); + break; + } + currentNode = currentNode->GetNext(); + } + } + } + + // Removes the node with the specified number value from the list. Returns + // true if the node is found and removed, false otherwise. + bool Remove(double number) { + // deal with having an empty list + if (head == nullptr) { + return false; + } + else { + Node *currentNode = head; + while (currentNode != nullptr) { + if (currentNode->GetData() == number) { + // Change around the adjacent nodes to point to each other + // Gotta deal with being the start or ending node + // (next or prev being nullptr), though + if (currentNode->GetPrevious() != nullptr) { + currentNode->GetPrevious()->SetNext(currentNode->GetNext()); + } + if (currentNode->GetNext() != nullptr) { + currentNode->GetNext()->SetPrevious(currentNode->GetPrevious()); + } + UpdateHead(currentNode); + UpdateTail(currentNode); + return true; + } + currentNode = currentNode->GetNext(); + } + return false; + } + } +}; + +#endif diff --git a/labs/cosc-2436/chapter-4/C++/main.cpp b/labs/cosc-2436/chapter-4/C++/main.cpp new file mode 100644 index 0000000..f7686d3 --- /dev/null +++ b/labs/cosc-2436/chapter-4/C++/main.cpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include "Node.h" +#include "SortedNumberList.h" +using namespace std; + +void PrintList(SortedNumberList& list); +vector SpaceSplit(string source); + +int main(int argc, char *argv[]) { + // Read the line of input numbers + string inputLine; + getline(cin, inputLine); + + // Split on space character + vector terms = SpaceSplit(inputLine); + + // Insert each value and show the sorted list's contents after each insertion + SortedNumberList list; + for (auto term : terms) { + double number = stod(term); + list.Insert(number); + cout << "List after inserting " << number << ": " << endl; + PrintList(list); + } + + /* + // Read the input line with numbers to remove + getline(cin, inputLine); + terms = SpaceSplit(inputLine); + + // Remove each value + for (auto term : terms) { + double number = stod(term); + cout << "List after removing " << number << ": " << endl; + list.Remove(number); + PrintList(list); + } + */ + + return 0; +} + +// Prints the SortedNumberList's contents, in order from head to tail +void PrintList(SortedNumberList& list) { + Node* node = list.head; + while (node) { + cout << node->GetData() << " "; + node = node->GetNext(); + } + cout << endl; +} + +// Splits a string at each space character, adding each substring to the vector +vector SpaceSplit(string source) { + vector result; + size_t start = 0; + for (size_t i = 0; i < source.length(); i++) { + if (' ' == source[i]) { + result.push_back(source.substr(start, i - start)); + start = i + 1; + } + } + result.push_back(source.substr(start)); + return result; +} diff --git a/labs/cosc-2436/chapter-4/Python/Node.py b/labs/cosc-2436/chapter-4/Python/Node.py new file mode 100644 index 0000000..a2fc60a --- /dev/null +++ b/labs/cosc-2436/chapter-4/Python/Node.py @@ -0,0 +1,31 @@ +class Node: + # Initializes this node with the specified numerical data value, next + # pointer, and previous pointer. + def __init__(self, initial_data, next_node=None, previous_node=None): + self.data = initial_data + self.next = next_node + self.previous = previous_node + + # Returns this node's data. + def get_data(self): + return self.data + + # Sets this node's data. + def set_data(self, new_data): + self.data = new_data + + # Gets this node's next pointer. + def get_next(self): + return self.next + + # Sets this node's next pointer. + def set_next(self, new_next): + self.next = new_next + + # Gets this node's previous pointer. + def get_previous(self): + return self.previous + + # Sets this node's previous pointer. + def set_previous(self, new_previous): + self.previous = new_previous diff --git a/labs/cosc-2436/chapter-4/Python/README.md b/labs/cosc-2436/chapter-4/Python/README.md new file mode 100644 index 0000000..ed103cb --- /dev/null +++ b/labs/cosc-2436/chapter-4/Python/README.md @@ -0,0 +1,78 @@ +# 4.16 LAB: Sorted number list implementation with linked lists - Python + +## Step 1: Inspect the Node.py file + +Inspect the class declaration for a doubly-linked list node in Node.py. Access Node.py by clicking on the orange arrow next to main.py at the top of the coding window. The Node class has three attributes: + +- a floating-point data value, +- a reference to the next node, and +- a reference to the previous node. + +Node.py is read only, since no changes are required. +Step 2: Implement the insert() method + +A class for a sorted, doubly-linked list is declared in SortedNumberList.py. Implement the SortedNumberList class's insert() method. The method must create a new node with the parameter value, then insert the node into the proper sorted position in the linked list. Ex: Suppose a SortedNumberList's current list is `23 → 47.25 → 86`, then `insert(33.5)` is called. A new node with data value 33.5 is created and inserted between 23 and 47.25, thus preserving the list's sorted order and yielding: `23 → 35.5 → 47.25 → 86` + +## Step 3: Test in develop mode + +Code in main() takes a space-separated list of numbers and inserts each into a SortedNumberList. The list is displayed after each insertion. Ex: If input is + +```txt +77 15 -42 63.5 +``` + +then output is: + +```txt +List after inserting 77: +77 +List after inserting 15: +15 77 +List after inserting -42: +-42 15 77 +List after inserting 63.5: +-42 15 63.5 77 +``` + +Try various program inputs, ensuring that each outputs a sorted list. + +## Step 4: Implement the remove() method + +Implement the SortedNumberList class's remove() method. The method takes a parameter for the number to be removed from the list. If the number does not exist in the list, the list is not changed and false is returned. Otherwise, the first instance of the number is removed from the list and true is returned. + +Uncomment the commented-out part in main() that reads a second input line and removes numbers from the list. Test in develop mode to ensure that insertion and removal both work properly, then submit code for grading. + +Ex: If input is + +```txt +84 72 19 61 +19 84 +``` + +then output is: + +```txt +List after inserting 84: +84 +List after inserting 72: +72 84 +List after inserting 19: +19 72 84 +List after inserting 61: +19 61 72 84 +List after removing 19: +61 72 84 +List after removing 84: +61 72 +``` + +--- + +```txt +PASS: Inserting 25.5 yields ( 25.5 ) +PASS: Inserting 75.75 yields ( 25.5, 75.75 ) +PASS: Inserting 88.5 yields ( 25.5, 75.75, 88.5 ) +FAIL: Insert 30: +Expected list: ( 25.5, 30, 75.75, 88.5 ) +Actual list: ( 30, 75.75, 88.5 ) +``` diff --git a/labs/cosc-2436/chapter-4/Python/SortedNumberList.py b/labs/cosc-2436/chapter-4/Python/SortedNumberList.py new file mode 100644 index 0000000..51c3329 --- /dev/null +++ b/labs/cosc-2436/chapter-4/Python/SortedNumberList.py @@ -0,0 +1,63 @@ +from Node import Node + + +class SortedNumberList: + def __init__(self): + self.head = None + self.tail = None + + # Inserts the number into the list in the correct position such that the + # list remains sorted in ascending order. + def insert(self, number): + if self.head == None: + self.head = Node(number) + self.tail = self.head + else: + current_node = self.head + new_node = Node(number) + while True: + # handles most stuff + # probably got an error cuz this is confusing + if current_node != None and current_node.get_data() >= number: + new_node.set_next(current_node) + new_node.set_previous(current_node.get_previous()) + + if new_node.get_previous() != None: + new_node.get_previous().set_next(new_node) + else: + self.head = new_node + + current_node.set_previous(new_node) + break + + # handles being at the end + if current_node == None: + self.tail.set_next(new_node) + new_node.set_previous(self.tail) + self.tail = new_node + break + + current_node = current_node.get_next() + + # Removes the node with the specified number value from the list. Returns + # True if the node is found and removed, False otherwise. + def remove(self, number): + current_node = self.head + while True and current_node != None: + if current_node.get_data() == number: + next_node = current_node.get_next() + previous_node = current_node.get_previous() + if next_node != None: + next_node.set_previous(previous_node) + else: + self.tail = previous_node + + if previous_node != None: + previous_node.set_next(next_node) + else: + self.head = next_node + return True + + current_node = current_node.get_next() + + return False diff --git a/labs/cosc-2436/chapter-4/Python/__pycache__/Node.cpython-311.pyc b/labs/cosc-2436/chapter-4/Python/__pycache__/Node.cpython-311.pyc new file mode 100644 index 0000000..04378d1 Binary files /dev/null and b/labs/cosc-2436/chapter-4/Python/__pycache__/Node.cpython-311.pyc differ diff --git a/labs/cosc-2436/chapter-4/Python/__pycache__/SortedNumberList.cpython-311.pyc b/labs/cosc-2436/chapter-4/Python/__pycache__/SortedNumberList.cpython-311.pyc new file mode 100644 index 0000000..28d1f60 Binary files /dev/null and b/labs/cosc-2436/chapter-4/Python/__pycache__/SortedNumberList.cpython-311.pyc differ diff --git a/labs/cosc-2436/chapter-4/Python/main.py b/labs/cosc-2436/chapter-4/Python/main.py new file mode 100644 index 0000000..0533ada --- /dev/null +++ b/labs/cosc-2436/chapter-4/Python/main.py @@ -0,0 +1,35 @@ +from SortedNumberList import SortedNumberList + + +def main(): + # Read the line of input numbers + terms = input().split() + + sorted_list = SortedNumberList() + # Insert each value and show the sorted list's contents after each insertion + for term in terms: + number = float(term) + print(f"""List after inserting {number}: """) + sorted_list.insert(number) + print_list(sorted_list) + + # Read the input line with numbers to remove + terms = input().split() + for term in terms: + number = float(term) + print(f"""List after removing {number}: """) + sorted_list.remove(number) + print_list(sorted_list) + + +# Prints the sorted_number_list's contents, in order from head to tail +def print_list(lst): + node = lst.head + while node != None: + print(node.get_data(), end=' ') + node = node.get_next() + print() + + +if __name__ == '__main__': + main() diff --git a/labs/database-programming/lab-2/instructions.md b/labs/database-programming/lab-2/instructions.md new file mode 100644 index 0000000..4cb20df --- /dev/null +++ b/labs/database-programming/lab-2/instructions.md @@ -0,0 +1,102 @@ +# Lab 2 + +*UPDATED: 12 Feb. Clarified scenario 6, 7 and 8.* + +This lab has you practice advanced queries against tables with aggregates, grouping and subqueries. + +For each scenario: + +- Include the scenario # +- The SQL query (properly formatted) + +*Note: DO NOT hard code any primary key IDs in your queries.* + +This lab uses the `WideWorldImporters` database. + +## Scenario 1 + +Get the lowest (as `LowestTemperature`) and highest temperature (as `HighestTemperature`) recorded for the vehicle temperatures (`Warehouse.VehicleTemperatures`). + +Rows: 1 + +## Scenario 2 + +Gets the list of `SalesPersonPersonID` and their total sales order counts (as `TotalOrders`) from `Sales.Orders`. + +Order the results by the highest total orders. + +Rows: 10 + +## Scenario 3 + +Get the customer ID and total number of invoices (as `TotalInvoices`) from `Sales.Invoices` for the year 2015. + +Group the invoices by the customer ID. + +Order the results by the highest number of invoices descending followed by the customer ID. + +Rows: 657 + +## Scenario 4 + +Get the order ID and total price (as `TotalOrderPrice`) from `Sales.Orders` for the customer `Debbie Molina` for the year 2016. +The total order price is the `Quantity` x `UnitPrice` of the order lines associated with the order. + +Order the results by the total price from highest to lowest. + +Rows: 10 + +## Scenario 5 + +Get the customer ID and total orders (as `TotalOrders`) from `Sales.Orders` for all customers who have at least 20 orders in 2016. + +Order the results by the total orders descending and then by customer ID. + +Rows: 87 + +## Scenario 6 + +Get the stock item ID, stock item name from and total quantity sold of the top 50 stock items sold (based upon quantity) of all time. + +Order the results by the total quantity descending. + +This will require two queries. The first query will get the stock items and the total quantity sold from the `OrderLines` table. For example if stock item 1 +is on 3 orders with a quantity of 1, 3 and 5 then the total quantity is 9. + +The second query will combine the stock item totals with the stock items from `Warehouse.StockItems` to get the top 50 items. + +*Note: This is using `OrdersLines` and not `InvoiceLines`.* + +*Note: This requires a subquery or CTE. A join by itself will not work.* + +Rows: 50 + +## Scenario 7 + +Get the customer ID, customer name and total orders for the top 10 customers who have the LEAST number of orders. + +Order the results by total orders and then by customer name. + +This will require two queries. The first query will get the customers and their total orders. + +The second query will combine the total order query with the remaining customer data to get the top 10. + +*Note: Some customers may have no orders so they should show up in the top 10, if they exist.* + +*Note: This will require either a subquery or a CTE.* + +Rows: 10 + +## Scenario 8 + +Get the delivery method ID and name from `Application.DeliveryMethods` that are not used in the `Sales.Customers` table. + +Order by the delivery method name. + +This will require two queries. The first query should get the delivery methods that are not being used. + +The second query should combine the unused methods with the remaining data needed to generate the desired results. + +*Note: This will require either a subquery or a CTE.* + +Rows: 9 diff --git a/labs/database-programming/lab-2/lab-2.sql b/labs/database-programming/lab-2/lab-2.sql new file mode 100644 index 0000000..f430414 --- /dev/null +++ b/labs/database-programming/lab-2/lab-2.sql @@ -0,0 +1,73 @@ +USE WideWorldImporters + +-- Scenario 1 +SELECT MIN(Temperature) AS LowestTemperature, MAX(Temperature) AS HighestTemperature +FROM Warehouse.VehicleTemperatures + +-- Scenario 2 +SELECT SalesPersonPersonID, COUNT(*) AS TotalOrders +FROM Sales.Orders +GROUP BY SalesPersonPersonID +ORDER BY TotalOrders + +-- Scenario 3 +SELECT CustomerID, SUM(InvoiceID) AS TotalInvoices +FROM Sales.Invoices +WHERE InvoiceDate BETWEEN '1/1/2015' AND '12/31/2015' +GROUP BY CustomerID +ORDER BY TotalInvoices, CustomerID + +-- Scenario 4 +SELECT od.OrderID, ol.Quantity * ol.UnitPrice AS TotalOrderPrice +FROM Sales.Orders od + JOIN Sales.OrderLines ol ON ol.OrderID = od.OrderID + JOIN Sales.Customers cu ON od.CustomerID = cu.CustomerID +WHERE cu.CustomerName = 'Debbie Molina' AND od.OrderDate BETWEEN '1/1/2016' AND '12/31/2016' +ORDER BY TotalOrderPrice + +-- Scenario 5 +SELECT * +FROM (SELECT CustomerID, COUNT(OrderID) AS TotalOrders + FROM Sales.Orders + WHERE OrderDate BETWEEN '1/1/2016' AND '12/31/2016' + GROUP BY CustomerID) Results +WHERE TotalOrders >= 20 +ORDER BY TotalOrders DESC, CustomerID + +-- Scenario 6 +WITH + Results + AS + ( + SELECT TOP 50 + ol.StockItemID, SUM(Quantity) TotalQuantity + FROM Sales.OrderLines ol + JOIN Warehouse.StockItems si ON ol.StockItemID = si.StockItemID + GROUP BY ol.StockItemID + ORDER BY TotalQuantity DESC + ) +SELECT Results.StockItemID, StockItemName, TotalQuantity +FROM Results JOIN Warehouse.StockItems ON WareHouse.Stockitems.StockItemID = Results.StockItemID +ORDER BY TotalQuantity DESC + +-- Scenario 7 +WITH + Results + AS + ( + SELECT cu.CustomerID, COUNT(OrderID) OrderCount + FROM Sales.Customers cu + LEFT JOIN Sales.Orders od ON cu.CustomerID = od.CustomerID + GROUP BY cu.CustomerID + ) +SELECT TOP 10 + Results.CustomerID, CustomerName, OrderCount +FROM Results + JOIN Sales.Customers ON Results.CustomerID = Sales.Customers.CustomerID + +-- Scenario 8 +SELECT DeliveryMethodID +FROM Application.DeliveryMethods +WHERE DeliveryMethodID NOT IN (SELECT DeliveryMethodID +FROM Sales.Customers) +ORDER BY DeliveryMethodName \ No newline at end of file diff --git a/labs/excel-thing b/labs/excel-thing new file mode 100644 index 0000000..b3c908c Binary files /dev/null and b/labs/excel-thing differ