Разработка запросов на Transact-SQL Lab 1 – Introduction to Transact-SQL Challenge 1.1: Retrieve Customer Data 1. Retrieve customer details Показать все поля и записи из таблицы Customer. 2. Retrieve customer name data Показать поля title, first name, middle name, last name, suffix по всем покупателям. 3. Retrieve customer names and phone numbers Список для обзвона покупателей, поля: • salesperson • Колонка с названием CustomerName показывающая как обращаться к покупателю (например, “Mr Smith”) title + lastname через пробел • phone. Challenge 1.2: Retrieve Customer and Sales Data 1. Retrieve a list of customer companies Список в формате номер покупателя потом через двоеточие и пробел название его компании <Customer ID>: <Company Name> Например: 78: Preferred Bikes 2. Retrieve a list of sales order revisions В таблице SalesLT.SalesOrderHeader сведения о продажах. Показать: • номер заказа, после него в скобках номер доработки <Order Number> (<Revision>) – например SO71774 (2) • дату заказа order date в российском стандарте (dd.mm.yyyy – например 31.01.2015). Challenge 1.3: Retrieve Customer Contact Details 1. Retrieve customer contact names with middle names if known Напечатать полное имя покупателя. Если middle name не известно, то в формате <first name> <last name> (for example Keith Harris), если известно, то <first name> <middle name> <last name> (for example Jane M. Gates). 2. Retrieve primary contact details У покупателя указан email address или phone number, возможно оба. Если есть email, то используется он, иначе телефон. Напечатать список номеров покупателей customer IDs и колонку PrimaryContact в которой email address, если он известен, а иначе телефон phone number. 3. Retrieve shipping status Показать номер заказа sales order Ids, дату заказа order dates и в колонке ShippingStatus слово “Shipped” для заказов у которых известна дата доставки ship date, либо “Awaiting Shipment” для заказов с пустой датой доставки ship date. Lab 2 – Querying Tables with SELECT Challenge 2.1: Retrieve Data for Transportation Reports 1. Retrieve a list of cities Показать список City и StateProvince, исключив дубли. 2. Retrieve the heaviest products Показать 10 самых тяжелых (weight) товаров (products). 3. Retrieve the heaviest 100 products not including the heaviest ten Показать следующие за первыми десятью, 100 самых тяжелых товаров. Challenge 2.2: Retrieve Product Data 1. Retrieve product details for product model 1 Показать: names, colors, и sizes товара с product model ID равным 1. 2. Filter products by color and size Показать product number и name черного, красного, белого товаров с размером S и M, color = 'black', 'red', или 'white' и size = 'S' or 'M'. 3. Filter products by product number Показать product number, name, and list price продуктов с номером product number начинающимся на 'BK-'. 4. Retrieve specific products by product number Изменить предыдущий запрос так чтобы product number начинался на 'BK-', но за тире не шла буква 'R’, а заканчивался номер на '-' (тире) и две цифры. Lab 3 – Querying Multiple Tables with Joins Challenge 3.1: Generate Invoice Reports 1. Retrieve customer orders Показать название компании покупателя company name из таблицы SalesLT.Customer, и номер заказа с общей суммой заказа sales order ID, total due из таблицы SalesLT.SalesOrderHeader. 2. Retrieve customer orders with addresses Добавить в список адрес главного офиса Main Office для каждого покупателя, including the full street address, city, state province, postal code, and country region Challenge 3.2: Retrieve Sales Data 1. Retrieve a list of all customers and their orders Показать всех покупателей: название компании customer companies и контактное лицо (first name and last name), номер заказа sales order ID и сумму заказа total due каждой покупки. Покупателей не совершавших покупок показать в конце списка с NULL в колонках с номером и суммой заказа. 2. Retrieve a list of customers with no address Продавцы обратили внимание, что Adventure Works не знает адреса некоторых покупателей. Показать список всех покупателей, у которых неизвестен адрес: customer IDs, company names, contact names (first name and last name), и phone numbers. 3. Retrieve a list of customers and products without orders Некоторые покупатели не совершали покупок, и некоторые товары никогда не покупались. Покажите номера таких покупателей customer IDs и товаров product Ids одним списком. В строках будет заполнено только одно поле customer ID, либо product ID другое будет NULL. Используйте FULL JOIN Lab 4 – Using Set Operators Challenge 4.1: Retrieve Customer Addresses 1. Retrieve billing addresses Покажите название покупателя company name, первую строку адреса, город city, и колонку с названием AddressType и значением ‘Billing’ для адресов тип которых address type в таблице SalesLT.CustomerAddress равен ‘Main Office’. 2. Retrieve shipping addresses Аналогичный запрос, но в колонке AddressType напишите ‘Shipping’ для адресов из SalesLT.CustomerAddress с типом ‘Shipping’. 3. Combine billing and shipping addresses Объедините результаты первых двух запросов, упорядочив результат по company name и address type. Challenge 4.2: Filter Customer Addresses 1. Retrieve customers with only a main office address Покажите company name для покупателей, которые есть в таблице с ‘Main Office’ адресами, но отсутствуют в таблице с ‘Shipping’ адресами. 2. Retrieve only customers with both a main office address and a shipping address Покажите company name покупателей у которых есть оба адреса ‘Main Office’ и ‘Shipping’. Lab 5 – Using Functions and Aggregating Data Challenge 5.1: Retrieve Product Information 1. Retrieve the name and approximate weight of each product Покажите номер товара product ID, его название name большими буквами и в колонке ApproxWeight вес округленный до целого. 2. Retrieve the year and month in which products were first sold Добавьте в запрос колонки SellStartYear и SellStartMonth, содержащие год и месяц начала продажи товара started selling date. Месяц в виде имени (например, ‘January’). 3. Extract product types from product numbers Добавьте в запрос колонку ProductType содержащую два самых левых символа из номера товара product number. 4. Retrieve only products with a numeric size Добавьте в запрос фильтр, чтобы показывались только те товары, у которых размер size задан числом. Challenge 5.2: Rank Customers by Revenue 1. Retrieve companies ranked by sales totals Покажите список company names, сумму продажи TotalDue из таблицы SalesOrderHeader и ранг продажи, первый ранг у максимальной продажи. Challenge 5.3: Aggregate Product Sales 1. Retrieve total sales by product Покажите имя товара name и общую сумму его продаж, как sum по полю LineTotal из таблицы SalesLT.SalesOrderDetail, в начале товары с максимальной суммой. 2. Filter the product sales list to include only products that cost over $1,000 В предыдущем запросе оставьте товары с ценой list price больше $1000. 3. Filter the product sales groups to include only total sales over $20,000 В предыдущем запросе оставьте товары с общей суммой продаж больше $20,000. Lab 6 – Using Subqueries and APPLY Challenge 6.1: Retrieve Product Price Information 1. Retrieve products whose list price is higher than the average unit price Покажите product ID, name, и list price для каждого товара list price которого больше среднего значения unit price по всем проданным товарам. 2. Retrieve Products with a list price of $100 or more that have been sold for less than $100 Покажите product ID, name, and list price товаров рекомендованная цена которых list price больше или равна $100, но были продажи unit price меньше $100. 3. Retrieve the cost, list price, and average selling price for each product Покажите по каждому товару product ID, name, cost, list price, а также среднюю цену по которой он продается unit price. 4. Retrieve products that have an average selling price that is lower than the cost В предыдущем запросе оставьте только те товары у которых себестоимость standard cost выше средней цены продажи unit price. Challenge 6.2: Retrieve Customer Information 1. Retrieve customer information for all sales orders Покажите sales order ID, customer ID, first name, last name, и total due по всем продажам из таблицы SalesLT.SalesOrderHeader, а имя покупателя из функции dbo.ufnGetCustomerInformation. 2. Retrieve customer address information Покажите customer ID, first name, last name, address line 1 and city по всем покупателям из таблиц SalesLT.Address, SalesLT.CustomerAddress, и функции dbo.ufnGetCustomerInformation. Lab 7 – Using Table Expressions Challenge 7.1: Retrieve Product Information 1. Retrieve product model descriptions Покажите product ID, product name, product model name, и product model summary для товаров из таблицы SalesLT.Product и представления SalesLT.vProductModelCatalogDescription. 2. Create a table of distinct colors Tip: см. Variables in Transact-SQL Language Reference. 3. Retrieve product parent categories В базе данных AdventureWorksLT есть табличная переменная dbo.ufnGetAllCategories, она возвращает таблицу категорий товаров product categories (например, ‘Road Bikes’) с родительскими категориями (например, ‘Bikes’). Используя функцию, покажите список всех товаров с их категориями и родительскими категориями. Challenge 7.2: Retrieve Customer Sales Revenue 1. Retrieve sales revenue by customer and contact Покажите список покупателей в формате Company (Contact Name) и общую сумму покупок. Сделайте двумя способами через производные таблицы (derived table) или обобщенные табличные выражения (common table expression) получить название компании в нужном формате и сумму заказа, а внешний запрос уже агрегирует и считает сумму. Lab 8 – Grouping Sets and Pivoting Data Challenge 8.1: Retrieve Regional Sales Totals 1. Retrieve totals for country/region and state/province Tip: см. GROUP BY in the Transact-SQL Language Reference. 2. Indicate the grouping level in the results Tip: см. GROUPING_ID function in the Transact-SQL Language Reference. 3. Add a grouping level for cities Добавьте в запрос суммы по городам. Challenge 8.2: Retrieve Customer Sales Revenue by Category 1. Retrieve customer sales revenue for each parent category Tip: см. PIVOT operator in the FROM clause syntax in the Transact-SQL language reference. Lab 9 – Modifying Data Challenge 9.1: Inserting Products 1. Insert a product Adventure Works начинает продажи нового товара. Добавьте его в таблицу SalesLT.Product, используйте значения по умолчанию либо NULL для не указанных полей: 2. Insert a new category with two products Adventure Works добавляет новую категорию товаров ‘Bells and Horns’. Родительская категория для нее 4 (Accessories). Новая категория содержит два новых товара: Challenge 9.2: Updating Products 1. Update product prices Увеличьте цену (list price) на 10% для товаров из категории ‘Bells and Horns’. ); 2. Discontinue products Новый товар «LED lights» добавленный выше, заменяет все предыдущие аналогичные товары. Измените таблицу SalesLT.Product задав текущую дату в поле DiscontinuedDate для всех товаров из категории «Lights» (Product Category ID = 37) кроме нового товара (ProductNumber LT-L123). Challenge 9.3: Deleting Products 1. Delete a product category and its products Удалите записи о категории «Bells and Horns» и ее продуктах. Удалять нужно в правильном порядке, чтобы не нарушить ограничение внешнего ключа. Lab 10 – Programming with Transact-SQL Challenge 10.1: Creating scripts to insert sales orders 1. Write code to insert an order header Напишите скрипт, добавляющий запись о покупке указав в переменных: order date, due date, и customer ID. Значение SalesOrderID генерируется сначала в переменную из последовательности SalesLT.SalesOrderNumber, которая создана в базе данных AdventureWorksLT. Скрипт должен вставлять запись в таблицу SalesLT.SalesOrderHeader указанные выше переменные и заданное прямо в команде insert значение ‘CARGO TRANSPORT 5’ для метода доставки (shipping method), в остальные колонки занести значения по умолчанию или NULL. После вставки записи показать значение, добавленное в поле SalesOrderID используя команду PRINT. 2. Write code to insert an order detail Скрипт вставляющий запись в order detail должен использовать переменные для указания: sales order ID, a product ID, a quantity, и unit price. Скрипт должен проверять существование продажи с указанным номером в таблице SalesLT.SalesOrderHeader. Если продажа существует, то расшифровка по ней вставляется в таблицу SalesLT.SalesOrderDetail (используйте значения по умолчанию или NULL для не указанных столбцов). Если sales order ID не существует в таблице SalesLT.SalesOrderHeader, напечатать сообщение ‘The order does not exist’. Существование записи можно проверить предикатом EXISTS. Проверьте скрипт на следующих значениях: Challenge 10.2: Updating Bike Prices 1. Write a WHILE loop to update bike prices цикл должен: • • • • Выполняться пока средняя цена (list price) всех товаров с родительской категорией ‘Bikes’ меньше заданной отделом маркетинга. Категории для которых «Bikes»родительская можно определить из проекции (view) SalesLT.vGetAllCategories. Обновлять все товары, входящие в родительскую категорию ‘Bikes’, увеличивая цену (list price) на 10%. Определять новую среднюю и максимальную цену товаров родительской категории ‘Bikes’. Если максимальная цена больше или равна заданному максимуму выходить из цикла, иначе продолжать дальше. После цикла напечатать получившиеся новые среднюю и максимальную цены Lab 11 – Error Handling and Transactions Challenge 11.1: Logging Errors 1. Throw an error for non-existent orders Следующий код удаляет сведения о покупке: DECLARE @SalesOrderID int = <the_order_ID_to_delete> DELETE FROM SalesLT.SalesOrderDetail WHERE SalesOrderID = @SalesOrderID; DELETE FROM SalesLT.SalesOrderHeader WHERE SalesOrderID = @SalesOrderID; Код выполняется даже если указан не существующий номер продажи. Добавьте проверку на существование покупки с указанным номером перед удалением. Если продажа не существует выдайте ошибку через THROW, иначе удалите ее. Challenge 11.2: Ensuring Data Consistency 1. Implement a transaction Улучшите предыдущий код поместив обе команды DELETE в транзакцию. Модифицируйте обработку ошибок так чтобы если транзакция открыта @@ TRANCOUNT>0, то она откатывается и на клиента возвращается ошибка повторным вызовом THROW. Если нет открытых транзакций, то просто выводится сообщение об ошибке, как и в предыдущем случае. Для проверки работы транзакции, добавьте команду THROW между двумя DELETE, эмулируя непредвиденную ошибку. В этом случае при попытке удалить существующие записи выдаются ошибки и обе таблицы остаются неизменными, сохраняя ссылочную целостность.