Вариант № 2 Вклады физических лиц в коммерческом банке Типовые объекты предметной области (сущности): Клиент, Счет, Вклад.
Связи объектов < Клиент > М ------ N < Вклад > поддерживается через счет вклада и операции по счету.
Атрибуты сущностей: Клиент
Виды вкладов (справочник)
Вклад клиента
Счет по вкладу
Дай мне скрипт создающий все это и устанавливающий нужные ключи. Я работаю в sql server managment studio 19
Задания на обработку данных
Для создания структуры базы данных и выполнения указанных заданий необходимо выполнить ряд шагов. Предполагается, что база данных еще не существует и нужно создать все с нуля. Описанные сущности и связи можно реализовать с помощью следующих SQL-команд.
Для начала создаем структуру базы данных:
-- Создание таблицы для клиентов CREATE TABLE Клиент ( №_клиента INT PRIMARY KEY, ФИО NVARCHAR(255), Паспортные_данные NVARCHAR(100), Фактический_адрес NVARCHAR(100), Адрес_регистрации NVARCHAR(255), Телефоны NVARCHAR(100) ); -- Создание таблицы для видов вкладов CREATE TABLE Виды_Вкладов ( Название_вклада NVARCHAR(100) PRIMARY KEY, Валюта NVARCHAR(255), Процент NVARCHAR(255), Период_действия_начало DATE, Период_действия_конец DATE, Автоматическая_пролонгация BIT ); -- Создание таблицы для вкладов клиентов CREATE TABLE Вклад ( Вклад_ID INT PRIMARY KEY IDENTITY(1,1), №_клиента INT, Название_вклада NVARCHAR(100), Дата_открытия DATE, Дата_окончания DATE, FOREIGN KEY (№_клиента) REFERENCES Клиент(№_клиента), FOREIGN KEY (Название_вклада) REFERENCES Виды_Вкладов(Название_вклада) ); -- Создание таблицы для операций по счету CREATE TABLE Счет ( №_счета INT PRIMARY KEY, Вклад_ID INT, №_операции INT, Тип_операции NVARCHAR(50), Валюта NVARCHAR(3), Дата_операции DATE, Сумма_операции MONEY, FOREIGN KEY (Вклад_ID) REFERENCES Вклад(Вклад_ID) );
Далее переходим к выполнению заданий на обработку данных:
DECLARE @Паспортные_данные NVARCHAR(100) = 'Паспортные данные клиента'; -- пример данных SELECT В.Вклад_ID, В.Дата_открытия, В.Дата_окончания, СUM(С.Сумма_операции) OVER (PARTITION BY С.Вклад_ID) AS Итоговая_сумма FROM Клиент К JOIN Вклад В ON К.№_клиента = В.№_клиента JOIN Счет С ON В.Вклад_ID = С.Вклад_ID WHERE К.Паспортные_данные = @Паспортные_данные;
SELECT DISTINCT К.* FROM Клиент К JOIN Вклад В ON К.№_клиента = В.№_клиента JOIN (SELECT Вклад_ID, SUM(Сумма_операции) AS Сумма FROM Счет GROUP BY Вклад_ID) AS Суммы ON В.Вклад_ID = Суммы.Вклад_ID WHERE Суммы.Сумма > (SELECT AVG(Сумма) FROM Суммы);
CREATE PROCEDURE Изменить_№_клиента @Старый_№ INT, @Новый_№ INT AS
Чтобы удалить клиента с новым номером, а также все связанные с ним записи, нам нужно установить каскадное удаление. Это можно сделать через опцию ON DELETE CASCADE
в ограничениях внешних ключей таблиц, которые ссылаются на таблицу Клиент
. Предполагая, что каскадное удаление уже настроено, скрипт удаления будет выглядеть следующим образом:
DECLARE @Новый_№_клиента INT = [здесь новый номер клиента]; -- Установите новый номер клиента для удаления -- Удаление клиента и всех связанных записей DELETE FROM Клиент WHERE №_клиента = @Новый_№_клиента;
Если каскадное удаление не настроено, вам необходимо сначала вручную удалить все связанные записи из зависимых таблиц перед удалением клиента из таблицы Клиент
.
CREATE PROCEDURE НайтиВкладПоКлиенту @ФИО NVARCHAR(255) = NULL, @Паспортные_данные NVARCHAR(100) = NULL AS BEGIN -- Попытка найти вклад с наиближайшей датой окончания по ФИО или паспортным данным SELECT TOP 1 ВВ.Название_вклада, ВВ.Валюта FROM Клиент К INNER JOIN Вклад В ON К.№_клиента = В.№_клиента INNER JOIN Виды_Вкладов ВВ ON В.Название_вклада = ВВ.Название_вклада WHERE (LOWER(К.ФИО) = LOWER(@ФИО) OR К.Паспортные_данные = @Паспортные_данные) AND В.Дата_окончания >= GETDATE() ORDER BY В.Дата_окончания ASC; -- Возврат списка 5 наиболее популярных видов вкладов SELECT TOP 5 ВВ.Название_вклада, COUNT(*) AS Количество_договоров FROM Виды_Вкладов ВВ INNER JOIN Вклад В ON ВВ.Название_вклада = В.Название_вклада WHERE В.Дата_окончания >= GETDATE() GROUP BY ВВ.Название_вклада ORDER BY COUNT(*) DESC; END;
Чтобы использовать процедуру, нужно будет передать @ФИО
или @Паспортные_данные
в качестве аргументов:
-- Использование процедуры EXEC НайтиВкладПоКлиенту @ФИО = 'Иванов Иван Иванович'; -- ФИО для поиска -- ИЛИ EXEC НайтиВкладПоКлиенту @Паспортные_данные = '1234567890'; -- Паспортные данные для поиска
Обратите внимание, что процедура определит вклад с наиболее близкой датой окончания среди вкладов, у которых эта дата не истекла. Количество договоров возвращает те, по которым вклады еще действуют на текущую дату.
СUM(С.Сумма_операции) OVER (PARTITION BY С.Вклад_ID) Эта строка подчеркнута
Извините за путаницу. Функци SUM
в сочетании с OVER
использется для вычисления суммы значений столбца разбивке на группы, заданную помощью PARTITION BY
. В данном случае, запрос вычисляет суммуумм операций для каждого Вклад_ID
.
Однако моя предыдущая рекомендация была некректной. Для вычисления итоговой сумм по вкладу, более правильны подходом будет использование простого SUM
без OVER
. Ниже привен исправленный SQL-запрос:
SELECT В.Вклад_ID В.Дата_открытия, В._окончания, SUM(С.Сумма_опер) AS Итоговая_сумма FROM Кли К JOIN Вклад В ON К.№_клиента = В.№_клиента JOIN чет С ON В.Вклад_ID = С.Вклад_ID К.Паспортные_де = @Паспортные_данные;
SELECT DISTINCT К.* FROM Клиент К JOIN Вклад В ON К.NUM_клиента = В.NUM_клиента JOIN (SELECT Вклад_ID, SUM(Сумма_операции) AS Сумма FROM Счет GROUP BY Вклад_ID) AS Суммы ON В.Вклад_ID = Суммы.Вклад_ID WHERE Суммы.Сумма > (SELECT AVG(Сумма) FROM Суммы); Недопустимое имя объекта "Суммы".
Извините за путаницу, я видим, что у вас возникли проблемы с SQL-запросом. Так как в запросе используется подзапрос "С", следует заменить его на "Счет" и выполнить коррекцию суммирования. Вот исправленный запрос:
SELECT DISTINCT K.* FROM Клиент K JOIN Вклад V ON K.NUM_клиента = V.NUM_клиента JOIN (SELECT Вклад_ID, SUM(Сумма_операции) AS Сумма FROM Счет GROUP BY Вклад_ID) AS Суммы ON V.Вклад_ID = Суммы.Вклад_ID WHERE Суммы.Сумма > (SELECT AVG(Сумма) FROM Суммы);
Прошу прощения за предыдущую путаницу. Этот скорректированный запрос должен корректно выполниться и вернуть ожидаемые результаты.
SELECT DISTINCT К.* FROM Клиент К JOIN Вклад В ON К.NUM_клиента = В.NUM_клиента JOIN (SELECT Вклад_ID, SUM(Сумма_операции) AS Сумма FROM Счет GROUP BY Вклад_ID) AS Суммы ON В.Вклад_ID = Суммы.Вклад_ID WHERE Суммы.Сумма > (SELECT AVG(Сумма) FROM Суммы); Недопустимое имя объекта "Суммы".
Извините за недоразумение. Обнаруженная ошибка "Недопустимое имя объекта 'Суммы'" указывает на то, что SQL-движок не может распознать объект 'Суммы' во втором запросе SELECT AVG(Сумма) FROM Суммы
потому что это имя было использовано только как алиас в подзапросе (подзапросы не видны за пределами собственных запросов).
Чтобы исправить запрос, вы должны заменить внутреннее упоминание Суммы
на другой подзапрос, который будет вычислять среднюю сумму независимо, вот так:
SELECT DISTINCT K.* FROM Клиент K JOIN Вклад V ON K.NUM_клиента = V.NUM_клиента JOIN (SELECT Вклад_ID, SUM(Сумма_операции) AS Сумма FROM Счет GROUP BY Вклад_ID) AS Суммы_вкладов ON V.Вклад_ID = Суммы_вкладов.Вклад_ID WHERE Суммы_вкладов.Сумма > ( SELECT AVG(Сумма_операции) FROM (SELECT SUM(Сумма_операции) AS Сумма_операции FROM Счет GROUP BY Вклад_ID) AS Групповая_сумма );
В этом запросе подзапрос внутри AVG()
повторно суммирует операции по каждому вкладу и возвращает их для вычисления среднего значения по всей выборке.