Форум программистов, компьютерный форум, киберфорум
Microsoft SQL Server
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/6: Рейтинг темы: голосов - 6, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 13.04.2019
Сообщений: 9

Присваивание данных предыдущей строки

13.04.2019, 11:50. Показов 1267. Ответов 5
Метки sql (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день! Помогите пожалуйста SQL запросом.
Есть таблица "Покупки", поля - "клиент", "дата", "сумма покупки". И Таблица "Скидки" - в ней поля "дата" и "скидка" - в этой таблице хранятся данные о размере скидок, на каждый день КРОМЕ выходных.
Нужно вывести "клиент" "дата" и "Сумма покупки со скидкой". Если покупка совершена в выходной день, то скидка считается за предыдущий рабочий.
Делал через Left JOIN, но проблема в том, что не знаю как сделать расчет для покупки в выходной день.
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
13.04.2019, 11:50
Ответы с готовыми решениями:

Как получить значение из предыдущей строки результата?
Извините конечно... я тока начинаю изучать SQL так что сыльно не бейте)))) помогите... Как получить значение из предыдущей строки...

Присваивание переменной значения из сформированного из строки запроса
Сабж. Для примера declare @sqlStr as varchar(1000) declare @res as int declare @someVar as varchar(1) = '1' @sqlStr = ' ...

Учет данных предыдущей строки в следующей
Помогите, пожалуйста, кто может. Надо на кнопку в форме посадить процедуру условия. Есть поле СОСТОЯЛО и ВСЕГО (оно вычисляемое). Значения...

5
6 / 3 / 3
Регистрация: 13.04.2019
Сообщений: 5
13.04.2019, 13:01
1. Имхо, я бы в таком случае заполнял таблицу скидок на все дни, дабы аналитические запросы не усложнять.
2. Простой вариант решения под ваши условия привёл ниже.
3. Было бы полезно, если бы кто-нибудь подсказал более изящное решение (через какой-нибудь хитрый join, например, или через CTE). Т.к. в приведённом ниже решении, если потребуются ещё какие-то поля из таблицы 'discount', или даже если нужно будет просто вывести значение скидки, громоздкий подзапрос придётся копипастить во все необходимые места, а это и дополнительное место для ошибок, и проблемы с рефакторингом и, вероятно, проблемы с производительностью.

тестовые таблицы
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
CREATE TABLE buy
(
    customer_id INT NOT NULL,
    dt DATE NOT NULL,
    total money NOT NULL,
    CONSTRAINT pk_buy PRIMARY KEY (customer_id, dt)
)
 
CREATE TABLE discount
(
    dt DATE NOT NULL,
    VALUE FLOAT NOT NULL,
    CONSTRAINT pk_discount PRIMARY KEY (dt)
)
тестовые данные
SQL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
INSERT INTO buy (customer_id, dt, total) VALUES (1, '2019-01-01', 100)
INSERT INTO buy (customer_id, dt, total) VALUES (1, '2019-01-02', 200)
INSERT INTO buy (customer_id, dt, total) VALUES (1, '2019-01-03', 300)
INSERT INTO buy (customer_id, dt, total) VALUES (1, '2019-01-04', 400)
INSERT INTO buy (customer_id, dt, total) VALUES (1, '2019-01-05', 500)
INSERT INTO buy (customer_id, dt, total) VALUES (1, '2019-01-06', 600)
INSERT INTO buy (customer_id, dt, total) VALUES (1, '2019-01-07', 700)
INSERT INTO buy (customer_id, dt, total) VALUES (1, '2019-01-08', 800)
INSERT INTO buy (customer_id, dt, total) VALUES (1, '2019-01-09', 900)
 
INSERT INTO buy (customer_id, dt, total) VALUES (2, '2019-01-01', 10)
INSERT INTO buy (customer_id, dt, total) VALUES (2, '2019-01-02', 20)
INSERT INTO buy (customer_id, dt, total) VALUES (2, '2019-01-03', 30)
INSERT INTO buy (customer_id, dt, total) VALUES (2, '2019-01-04', 40)
INSERT INTO buy (customer_id, dt, total) VALUES (2, '2019-01-05', 50)
INSERT INTO buy (customer_id, dt, total) VALUES (2, '2019-01-06', 60)
INSERT INTO buy (customer_id, dt, total) VALUES (2, '2019-01-07', 70)
INSERT INTO buy (customer_id, dt, total) VALUES (2, '2019-01-08', 80)
INSERT INTO buy (customer_id, dt, total) VALUES (2, '2019-01-09', 90)
 
INSERT INTO discount (dt, VALUE) VALUES ('2019-01-01', 20)
INSERT INTO discount (dt, VALUE) VALUES ('2019-01-02', 22)
INSERT INTO discount (dt, VALUE) VALUES ('2019-01-03', 24)
INSERT INTO discount (dt, VALUE) VALUES ('2019-01-04', 26)
INSERT INTO discount (dt, VALUE) VALUES ('2019-01-05', 50)
-- insert into discount (dt, value) values ('2019-01-06', 30)
-- insert into discount (dt, value) values ('2019-01-07', 30)
INSERT INTO discount (dt, VALUE) VALUES ('2019-01-08', 20)
INSERT INTO discount (dt, VALUE) VALUES ('2019-01-09', 22)
корявый вариант решения
SQL
1
2
3
4
5
6
SELECT buy.customer_id
, buy.dt
, buy.total
, buy.total * ((100 - (SELECT top 1 discount.value FROM discount WHERE discount.dt <= buy.dt ORDER BY discount.dt DESC)) / 100) AS total_with_discount
 
FROM buy
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
13.04.2019, 13:16
Оптимизируем и устраняем проблему "если потребуются ещё какие-то поля из таблицы 'discount', или даже если нужно будет просто вывести значение скидки, громоздкий подзапрос придётся копипастить во все необходимые места"
T-SQL
1
2
3
4
5
6
7
8
9
select
 b.customer_id,
 b.dt,
 b.total,
 b.total * ((100 - isnull(d.value, pd.value)) / 100) as total_with_discount
from
 buy b left join
 discount d on d.dt = b.dt outer apply
 (select top (1) value from discount where d.dt is null and dt < b.dt order by dt desc) pd;
1
0 / 0 / 0
Регистрация: 13.04.2019
Сообщений: 9
13.04.2019, 16:50  [ТС]
Рассчитывает сумму со всеми скидками. То есть покупка пятницы считается со всеми скидками которые есть в таблице "Скидки"

Добавлено через 4 минуты
Извиняюсь, что значит pd?
0
3614 / 2135 / 756
Регистрация: 02.06.2013
Сообщений: 5,169
13.04.2019, 19:01
Цитата Сообщение от TinyRi Посмотреть сообщение
Рассчитывает сумму со всеми скидками. То есть покупка пятницы считается со всеми скидками которые есть в таблице "Скидки"
Предложенный запрос такого делать не может. В принципе.
А какой запрос вы написали, нам неведомо.
Цитата Сообщение от TinyRi Посмотреть сообщение
Извиняюсь, что значит pd?
Читайте про алиасы таблиц и столбцов в запросе.
0
0 / 0 / 0
Регистрация: 13.04.2019
Сообщений: 9
14.04.2019, 10:59  [ТС]
Разобрался! Работает, но для покупки в воскресенье выводит NULL, т.к. за субботу скидки нет. Добавил в начало
While dt.<b.dt
Begin
select
b.customer_id,
b.dt,
b.total,
b.total * ((100 - isnull(d.value, pd.value)) / 100) as total_with_discount
from
buy b left join
discount d on d.dt = b.dt outer apply
(select top (1) value from discount where d.dt is null and dt < b.dt order by dt desc) pd;
End


Выдает ошибку - "Не удалось привязать составной идентификатор "Rates.Report_date"."

Как можно зациклить?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
14.04.2019, 10:59
Помогаю со студенческими работами здесь

Наименьший элемент каждой строки матрицы заменить наибольшим элементом предыдущей строки
Наименьший элемент каждой строки прямоугольной таблицы замените наибольшим элементом предыдущей строки.

Заменить наименьший элемент каждой строки матрицы наибольшим элементом предыдущей строки
Дана прямоугольная матрицаА(nxm). Заменить наименьший элемент каждой строки, начиная со второй, наибольшим элементом предыдущей строки.

Наименьший элемент каждой строки прямоугольной таблицы, замените наибольшим элементом предыдущей строки
Наименьший элемент каждой строки прямоугольной таблицы, замените наибольшим элементом предыдущей строки.

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

Заменить наименьший элемент каждой строки, начиная со второй, наибольшим элементом предыдущей строки
2.Дан массив А. Заменить наименьший элемент каждой строки, начиная со второй, наибольшим элементом предыдущей строки.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11680&amp;d=1772460536 Одним из. . .
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru