Conversation with Merlin [email protected] · Mon Dec 18 2023

Вариант № 2 Вклады физических лиц в коммерческом банке Типовые объекты предметной области (сущности): Клиент, Счет, Вклад.

Связи объектов < Клиент > М ------ N < Вклад > поддерживается через счет вклада и операции по счету.

Атрибуты сущностей: Клиент

  • №_клиента
  • ФИО клиента,
  • Паспортные данные клиента,
  • Фактический адрес клиента (Unicode до 100 символов),
  • Адрес регистрации,
  • Телефоны.

Виды вкладов (справочник)

  • Название вклада,
  • Валюта/несколько валют вклада (вклад может быть многовалютным), валюта – справочное данное,
  • Процент/проценты по каждой валюте по вкладу, зависят от срока размещения средств (справочник),
  • Период действия (даты начала и окончания приема средств),
  • Автоматическая пролонгация (Есть/Нет).

Вклад клиента

  • Дата открытия или дата пролонгации,
  • Дата окончания.

Счет по вкладу

  • № счета,
  • № операции по счету,
  • Тип операции (Приход, Расход),
  • Валюта,
  • Дата операции,
  • Сумма операции.

Дай мне скрипт создающий все это и устанавливающий нужные ключи. Я работаю в sql server managment studio 19

Задания на обработку данных

  1. Набор операторов Transact-SQL, который по заданным в переменной паспортным данным клиента выводит для каждого его вклада все атрибуты и рассчитывает по отдельным операциям счета итоговую сумму (остаток) по вкладу.
  2. Напишите скрипт, который возвращает все сведения о вкладчиках, у которых хотя бы на одном из счетов сумма остатка больше чем средняя сумма на остатков на счетах по всей базе.
  3. Создайте процедуру, которая изменяет первичный ключ клиента (№_клиента). Старое и новое значение ключа задаются параметрами процедуры.
  4. Напишите скрипт для удаления клиента, получившего новый номер. Вместе с записью о клиенте должны удаляться связанные с ней зависимые записи. 5 Напишите процедуру, которая по заданному параметром ФИО или паспортным данным клиента определяет название и валюту вклада с ближайшей датой окончания. В поле «ФИО» данные могут быть заданы и большими и маленькими буквами. При отсутствии указанного клиента процедура возвращает NULL. Кроме того, процедура возвращает список из 5 наиболее популярных видов вкладов. Наиболее популярными считаются те виды, по которым наибольшее количество действующих договоров.

Для создания структуры базы данных и выполнения указанных заданий необходимо выполнить ряд шагов. Предполагается, что база данных еще не существует и нужно создать все с нуля. Описанные сущности и связи можно реализовать с помощью следующих 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) );

Далее переходим к выполнению заданий на обработку данных:

  1. Получение информации о вкладах клиента по паспортным данным и расчет итоговой суммы по вкладу:
DECLARE @Паспортные_данные NVARCHAR(100) = 'Паспортные данные клиента'; -- пример данных SELECT В.Вклад_ID, В.Дата_открытия, В.Дата_окончания, СUM(С.Сумма_операции) OVER (PARTITION BY С.Вклад_ID) AS Итоговая_сумма FROM Клиент К JOIN Вклад В ON К.№_клиента = В.№_клиента JOIN Счет С ON В.Вклад_ID = С.Вклад_ID WHERE К.Паспортные_данные = @Паспортные_данные;
  1. Возвращение сведений о вкладчиках с остатком больше средней:
SELECT DISTINCT К.* FROM Клиент К JOIN Вклад В ON К.№_клиента = В.№_клиента JOIN (SELECT Вклад_ID, SUM(Сумма_операции) AS Сумма FROM Счет GROUP BY Вклад_ID) AS Суммы ON В.Вклад_ID = Суммы.Вклад_ID WHERE Суммы.Сумма > (SELECT AVG(Сумма) FROM Суммы);
  1. Создание процедуры для изменения первичного ключа клиента:
CREATE PROCEDURE Изменить_№_клиента @Старый_№ INT, @Новый_№ INT AS
  1. Напишите скрипт для удаления клиента, получившего новый номер. Вместе с записью о клиенте должны удаляться связанные с ней зависимые записи. 5 Напишите процедуру, которая по заданному параметром ФИО или паспортным данным клиента определяет название и валюту вклада с ближайшей датой окончания. В поле «ФИО» данные могут быть заданы и большими и маленькими буквами. При отсутствии указанного клиента процедура возвращает NULL. Кроме того, процедура возвращает список из 5 наиболее популярных видов вкладов. Наиболее популярными считаются те виды, по которым наибольшее количество действующих договоров.
  1. Скрипт для удаления клиента и связанных записей:

Чтобы удалить клиента с новым номером, а также все связанные с ним записи, нам нужно установить каскадное удаление. Это можно сделать через опцию ON DELETE CASCADE в ограничениях внешних ключей таблиц, которые ссылаются на таблицу Клиент. Предполагая, что каскадное удаление уже настроено, скрипт удаления будет выглядеть следующим образом:

DECLARE @Новый_№_клиента INT = [здесь новый номер клиента]; -- Установите новый номер клиента для удаления -- Удаление клиента и всех связанных записей DELETE FROM Клиент WHERE №_клиента = @Новый_№_клиента;

Если каскадное удаление не настроено, вам необходимо сначала вручную удалить все связанные записи из зависимых таблиц перед удалением клиента из таблицы Клиент.

  1. Процедура для определения вклада по ФИО или паспортным данным и возврата списка 5 наиболее популярных вкладов:
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() повторно суммирует операции по каждому вкладу и возвращает их для вычисления среднего значения по всей выборке.