- •Аннотация
- •Содержание
- •Введение
- •1. Формулировка задания
- •1.1. Задание
- •1.2. Структура идз
- •Описание предметной области
- •Проектирование базы данных
- •Создание бАзы данных
- •Создание таблиц и ограничений целостности
- •Заполнение таблиц данными
- •Заполнение таблицы «Staff» (Сотрудники)
- •Заполнение таблицы «Tables» (Столы):
- •Заполнение таблицы «Categories» (Категории)
- •Заполнение таблицы «MenuItems» (Меню)
- •Заполнение таблицы «Orders» (Заказы)
- •Заполнение таблицы «OrderItems» (Позиции заказа)
- •Заполнение таблицы «Payments» (Платежи)
- •Разработка объектов промежуточного слоя
- •Хранимые процедуры
- •Процедура «CreateOrder» для создания нового заказа
- •Процедура «AddItemToOrder» для добавления позиций в заказ
- •Процедура «SetOrderWaitingForPayment» для перевода заказа в статус ожидания оплаты
- •Процедура «PayOrder» для оплаты заказа
- •Представления
- •Представление «ActiveOrders» для просмотра активных заказов
- •Представление «WaiterDailyRevenue», показывающее выручку, принесённую каждым из официантов
- •Представление «DailyOrderStats», показывающее по дням заработок ресторана, оплаченные заказы, средний чек
- •Представление «OrdersByWaiterStatus», показывающее количество заказов, обслуженных каждым из официантов по статусам заказа
- •Функции
- •Скалярная функция «OrderTotal» для подсчета стоимости заказа
- •Табличная функция «GetOrdersWithTotal», которая возвращает блюда по заказам
- •Табличная функция «GetMenuItemsByAvailability», показывающая оставшиеся блюда
- •Табличная функция «GetLastOrderItems» возвращающая последние блюда в заказах
- •Скалярная функция «MenuItemSalesPaid» для подсчета проданных позиций блюд в день
- •Разработка триггеров
- •Триггер «InsertWaiterTable» для вставки в таблицу WaiterTables, когда происходит заказ
- •Триггер «CheckStock», уменьшающий количество блюд в MenuItems и предупреждающий, если блюда закончились
- •Триггер «PreventWaitingPaymentWithoutItems», проверяющий пустой заказ
- •Разработка стратегии резервного копирования и восстановления
- •Процедура полного резервного копирования
- •Процедура дифференциального резервного копирования
- •Процедура резервного копирования журнала транзакций
- •Процедура тестирования всех бэкапов
- •Автоматизация через sql server agent
- •Процедура восстановления
- •Заключение
- •Список использованных источников
Представления
Представление «ActiveOrders» для просмотра активных заказов
Если просто вывести все данные из таблицы «Orders», мы не увидим конечную сумму заказа. Поэтому создадим представление, которое выводит активные заказа, их дату, имя и фамилию официанта, номер стола, количество заказанных блюд и стоимость сумму для оплаты.
Запрос:
CREATE OR ALTER VIEW rest.vw_ActiveOrders AS
SELECT
o.OrderID,
o.OrderDateTime,
o.Status,
s.FirstName,
s.LastName,
t.TableNumber,
COUNT(oi.ItemID) AS ItemCount,
SUM(oi.Quantity * oi.UnitPrice) AS TotalAmount
FROM rest.Orders o
JOIN rest.Staff s ON o.WaiterID = s.StaffID
JOIN rest.Tables t ON o.TableID = t.TableID
LEFT JOIN rest.OrderItems oi ON o.OrderID = oi.OrderID
WHERE o.Status IN ('Принят', 'Ожидает оплаты')
GROUP BY
o.OrderID,
o.OrderDateTime,
o.Status,
s.FirstName,
s.LastName,
t.TableNumber;
GO
Пример использования:
SELECT OrderID,
OrderDateTime,
Status,
FirstName,
LastName,
TableNumber,
ItemCount,
TotalAmount
FROM rest.vw_ActiveOrders;
После выполнения запроса вывелась таблица с активными заказами (рис. 33).
Рисунок 33. Выполнение запроса
Представление «WaiterDailyRevenue», показывающее выручку, принесённую каждым из официантов
С помощью этого представления можно узнать, сколько выручки получил каждый из официантов, количество обслуженных им заказов, средний чек, количество принесенных блюд и количество обслуженных столов.
Запрос:
CREATE OR ALTER VIEW rest.vw_WaiterDailyRevenue AS
SELECT
CAST(o.OrderDateTime AS DATE) AS RevenueDate,
s.StaffID,
s.FirstName,
s.LastName,
COUNT(DISTINCT o.OrderID) AS OrdersServed,
SUM(p.Amount) AS TotalRevenue,
AVG(p.Amount) AS AverageOrderAmount,
SUM(oi.Quantity) AS ItemsSold,
COUNT(DISTINCT o.TableID) AS TablesServed
FROM rest.Staff s
JOIN rest.Orders o ON s.StaffID = o.WaiterID
JOIN rest.Payments p ON o.OrderID = p.OrderID
LEFT JOIN rest.OrderItems oi ON o.OrderID = oi.OrderID
GROUP BY
CAST(o.OrderDateTime AS DATE),
s.StaffID,
s.FirstName,
s.LastName;
GO
Пример использования:
SELECT RevenueDate,
StaffID,
FirstName,
LastName,
OrdersServed,
TotalRevenue,
AverageOrderAmount,
ItemsSold,
TablesServed
FROM rest.vw_WaiterDailyRevenue;
Выполнение запроса (рис. 34).
Рисунок 34. Пример работы представления выручки ресторана
Представление «DailyOrderStats», показывающее по дням заработок ресторана, оплаченные заказы, средний чек
С помощью этого представления можно узнать, сколько выручки получил ресторан в каждый из дней, количество активных заказов, средний чек, количество обслуженных столов, сумму самого дорого заказа.
Запрос:
CREATE OR ALTER VIEW rest.vw_DailyOrderStats AS
SELECT
CAST(o.OrderDateTime AS DATE) AS OrderDate,
COUNT(*) AS TotalOrders,
SUM(CASE WHEN o.Status = 'Оплачен' THEN 1 ELSE 0 END) AS PaidOrders,
SUM(CASE WHEN o.Status = 'Оплачен' THEN p.Amount + p.TipAmount ELSE 0 END) AS DailyRevenue,
AVG(CASE WHEN o.Status = 'Оплачен' THEN p.Amount + p.TipAmount END) AS AvgCheck,
MAX(CASE WHEN o.Status = 'Оплачен' THEN p.Amount + p.TipAmount END) AS MaxOrderValue,
SUM(COALESCE(oi.Quantity, 0)) AS TotalItemsSold,
COUNT(DISTINCT o.TableID) AS TablesServed,
SUM(CASE WHEN o.Status IN ('Принят', 'Ожидает оплаты') THEN 1 ELSE 0 END) AS ActiveOrders
FROM rest.Orders o
LEFT JOIN rest.Payments p ON o.OrderID = p.OrderID
LEFT JOIN rest.OrderItems oi ON o.OrderID = oi.OrderID
GROUP BY CAST(o.OrderDateTime AS DATE);
GO
Пример использования:
USE DataBase_Restaurant;
GO
SELECT
OrderDate,
TotalOrders,
PaidOrders,
DailyRevenue,
AvgCheck,
MaxOrderValue,
TotalItemsSold,
TablesServed,
ActiveOrders
FROM rest.vw_DailyOrderStats
ORDER BY OrderDate;
После выполнения запроса увидим таблицу, где расписана информация по заказам за два дня (рис. 35).
Рисунок 35. Пример работы представления заработка по дням
