powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вопрос по SQL-запросу
12 сообщений из 12, страница 1 из 1
Вопрос по SQL-запросу
    #39582490
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Здравствуйте!

Есть поле ТипСвязиТТ и имеет 4 значения:
0 - Это по всему юр лицу
1 - Это по первому признаку объединения ТТ
2 - Это по второму признаку объединения ТТ
3 - Это по непосресдственной одной ТТ

Есть первая таблица. Список мероприятии с участвующими SKU
КодМероприятияЮрЛицоТипСвязиТТКодТТНачалоМероприятияКонецМероприятияSKU00100111002.01.201803.01.2018SKU100200111101_00103.01.201804.01.2018SKU200300111202_00204.01.201805.01.2018SKU30040011130000405.01.201806.01.2018SKU40040011130000405.01.201806.01.2018SKU1
В одном мероприятии могут участвовать больше одной SKU, но периоды одинаковые. См. строки с кодами мероприятии 004.


Есть вторая таблица. Список ТТ
КодТТ ЮрЛицоПервыйПризнакОбъединенияВторойПризнакОбъединения000010011101_00102_001000020011101_00102_002000030011101_00202_003000040011101_00202_002

Нужно получить такую таблицуКодМероприятияЮрЛицоКодТТSKUДатаМероприятия0010011100001SKU102.01.20180010011100001SKU103.01.20180010011100002SKU102.01.20180010011100002SKU103.01.20180010011100003SKU102.01.20180010011100003SKU103.01.20180010011100004SKU102.01.20180010011100004SKU103.01.20180020011100001SKU203.01.20180020011100001SKU204.01.20180020011100002SKU203.01.20180020011100002SKU204.01.20180030011100002SKU304.01.20180030011100002SKU305.01.20180030011100004SKU304.01.20180030011100004SKU305.01.20180040011100004SKU405.01.20180040011100004SKU406.01.20180040011100004SKU105.01.20180040011100004SKU106.01.2018
Соединение делается таким образом, чтобы получилась таблица со следующими полями: Мероприятие+ЮрЛицо+КодТТ (который попадает через тип связи) +SKU (который участвует в мероприятии) +День (который попадает в период мероприятия).

Начал писать запрос и запутался.

1. Насколько я правильно понимаю, что на первом этапе создаем первую промежуточную таблицу: по каждому мероприятию создаем строки SKU+Дата. На втором этапе создаем вторую промежуточную таблицу: по каждому мероприятию создаются строки непосредственно участвующие ТТ, отобранные с помощью типов связи. На третьем этапе - Соединяем первую и вторую промежуточную таблицу. Для данной задачи по такому алгоритму нужно решать?

2. Для первого этапа пытаюсь использовать такую идею . Что то не получается. Как правильно написать запрос?

SQL-Запрос с исходными данными
Код: 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.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
declare @СписокМероприятий table
(КодМероприятия varchar (3),
	ЮрЛицо varchar (5),
	ТипСвязи integer,
	КодТТ varchar (8),
	НачалоМероприятия date,
	КонецМероприятия date,
	SKU varchar(4))

insert into @СписокМероприятий select '001', '00111',0,null,'02.01.2018', '03.01.2018', 'SKU1'
insert into @СписокМероприятий select '002', '00111',1,'01_001','03.01.2018', '04.01.2018', 'SKU2'
insert into @СписокМероприятий select '003', '00111',2,'02_002','04.01.2018', '05.01.2018', 'SKU3'
insert into @СписокМероприятий select '004', '00111',3,'00004','05.01.2018', '06.01.2018', 'SKU4'
insert into @СписокМероприятий select '004', '00111',3,'00004','05.01.2018', '06.01.2018', 'SKU1'

/*Select * FROM @СписокМероприятий*/



declare @СписокТТ table
(КодТТ varchar (5),
	ЮрЛицо varchar (5),
	ПервыйПризнакОбъединения varchar (6),
	ВторойПризнакОбъединения varchar (6))

insert into @СписокТТ select '00001', '00111','01_001','02_001'
insert into @СписокТТ select '00002', '00111','01_001','02_002'
insert into @СписокТТ select '00003', '00111','01_002','02_003'
insert into @СписокТТ select '00004', '00111','01_002','02_002'


/*Select * FROM @СписокТТ*/


declare @ПромежуточнаяТаблицаДаты table (Дата date)
declare @ПромежуточнаяДата datetime = '01.01.2018'

while @ПромежуточнаяДата <= '10.01.2018'
begin
insert @ПромежуточнаяТаблицаДаты (Дата) select @ПромежуточнаяДата
set @ПромежуточнаяДата = dateadd(dd,1,@ПромежуточнаяДата)
end

/*select * from @ПромежуточнаяТаблицаДаты*/

select
	КодМероприятия,
	ЮрЛицо,
	SKU
FROM
	@СписокМероприятий
outer apply
	(Select 
		Дата
	FROM
		@ПромежуточнаяТаблицаДаты
	where
		ПромежуточнаяТаблицаДаты.Дата >= СписокМероприятий.НачалоМероприятия 
		AND
		ПромежуточнаяТаблицаДаты.Дата <= СписокМероприятий.КонецМероприятия) AS Таблица



Если писать так
Код: sql
1.
2.
3.
4.
	where
		@ПромежуточнаяТаблицаДаты.Дата >= @СписокМероприятий.НачалоМероприятия 
		AND
		@ПромежуточнаяТаблицаДаты.Дата <= @СписокМероприятий.КонецМероприятия) AS Таблица

то пишет что нужно объявить скалярные переменные. А если убрать знак @, то пишет, что не удалось привязать составной идентификатор.

Почему так?

И возможно ли обойтись без @ПромежуточнаяТаблицаДаты? Все таки изначально не знаем какие начальные и конечные даты должны быть в этой таблице.
...
Рейтинг: 0 / 0
Вопрос по SQL-запросу
    #39582525
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По-моему, во второй таблице упущено поле SKU... без него не очень срастается.
...
Рейтинг: 0 / 0
Вопрос по SQL-запросу
    #39582543
Руслан Дамирович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Просьба убрать от мониторов кошек и детей, беременных и кормящих женщин, и других психически нестабильных личностей
Код: 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.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
DECLARE @СписокМероприятий TABLE
(КодМероприятия varchar (3),
	ЮрЛицо varchar (5),
	ТипСвязи integer,
	КодТТ varchar (8),
	НачалоМероприятия date,
	КонецМероприятия date,
	SKU varchar(4))
;
INSERT INTO
  @СписокМероприятий
VALUES 
  ( '001', '00111', 0,     NULL, '20180102', '20180103', 'SKU1' ),
  ( '002', '00111', 1, '01_001', '20180103', '20180104', 'SKU2' ),
  ( '003', '00111', 2, '02_002', '20180104', '20180105', 'SKU3' ),
  ( '004', '00111', 3,  '00004', '20180105', '20180106', 'SKU4' ),
  ( '004', '00111', 3,  '00004', '20180105', '20180106', 'SKU1' )
;
DECLARE @СписокТТ TABLE
(КодТТ varchar (5),
	ЮрЛицо varchar (5),
	ПервыйПризнакОбъединения varchar (6),
	ВторойПризнакОбъединения varchar (6))
;
INSERT INTO
  @СписокТТ 
VALUES 
  ( '00001', '00111', '01_001', '02_001' ),
  ( '00002', '00111', '01_001', '02_002' ),
  ( '00003', '00111', '01_002', '02_003' ),
  ( '00004', '00111', '01_002', '02_002' )
;
WITH
t AS (
  SELECT
    mm.[КодМероприятия],
    tt.[ЮрЛицо],
    tt.[КодТТ],
    mm.[SKU],
    [Дата] = mm.[НачалоМероприятия],
    mm.[КонецМероприятия]
  FROM
    @СписокМероприятий mm
    INNER JOIN @СписокТТ tt ON (
          1 = CASE
            WHEN mm.[ТипСвязи] = 0 AND tt.[ЮрЛицо] = mm.[ЮрЛицо] THEN 1
            WHEN mm.[ТипСвязи] = 1 AND tt.[ЮрЛицо] = mm.[ЮрЛицо] AND tt.[ПервыйПризнакОбъединения] = mm.[КодТТ] THEN 1
            WHEN mm.[ТипСвязи] = 2 AND tt.[ЮрЛицо] = mm.[ЮрЛицо] AND tt.[ВторойПризнакОбъединения] = mm.[КодТТ] THEN 1
            WHEN mm.[ТипСвязи] = 3 AND tt.[ЮрЛицо] = mm.[ЮрЛицо] AND tt.[КодТТ] = mm.[КодТТ] THEN 1
          END )
  UNION ALL
  SELECT
    t.[КодМероприятия],
    t.[ЮрЛицо],
    t.[КодТТ],
    t.[SKU],
    [Дата] = DATEADD( DAY, 1, t.[Дата] ),
    t.[КонецМероприятия]
  FROM
    t
  WHERE
    t.[Дата] < t.[КонецМероприятия]
)
SELECT
  [КодМероприятия],
  [ЮрЛицо],
  [КодТТ],
  [SKU],
  [Дата]
FROM
  t
ORDER BY
  1, 2, 3, 4, 5
OPTION (
  MAXRECURSION 0 )

...
Рейтинг: 0 / 0
Вопрос по SQL-запросу
    #39582557
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaПо-моему, во второй таблице упущено поле SKU... без него не очень срастается.
Вторая таблица отображает список ТТ и не имеет связи с SKU. Таблица отображает какая именно ТТ относится в группе для первого признака и в какой группе для второго признака, и какое юридическое лицо. Потом с помощью поля "Тип связи" и "Код ТТ" из первой таблицы вытаскиваются коды ТТ. Поле "Код ТТ" из первой таблицы, это не только код ТТ, но и Коды полей "ПервыйПризнакОбъединения" "ВторойПризнакОбъединения".
...
Рейтинг: 0 / 0
Вопрос по SQL-запросу
    #39582670
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Руслан Дамирович , я бы условие tt.[ЮрЛицо] = mm.[ЮрЛицо] в секции ON вынес за пределы CASE...
...
Рейтинг: 0 / 0
Вопрос по SQL-запросу
    #39582744
Руслан Дамирович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina Руслан Дамирович , я бы условие tt.[ЮрЛицо] = mm.[ЮрЛицо] в секции ON вынес за пределы CASE...
Когда будем оптимизировать - несомненно.
Но в общем случае и в отсутствие информации об индексах - возле птиц.
...
Рейтинг: 0 / 0
Вопрос по SQL-запросу
    #39582796
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Руслан Дамирович,

Спасибо, разбираю!
...
Рейтинг: 0 / 0
Вопрос по SQL-запросу
    #39582797
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikkЕсли писать так
Код: sql
1.
2.
3.
4.
	where
		@ПромежуточнаяТаблицаДаты.Дата >= @СписокМероприятий.НачалоМероприятия 
		AND
		@ПромежуточнаяТаблицаДаты.Дата <= @СписокМероприятий.КонецМероприятия) AS Таблица

то пишет что нужно объявить скалярные переменные. А если убрать знак @, то пишет, что не удалось привязать составной идентификатор.

Почему так?
Это бы понять еще
...
Рейтинг: 0 / 0
Вопрос по SQL-запросу
    #39582820
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Руслан ДамировичAkina Руслан Дамирович , я бы условие tt.[ЮрЛицо] = mm.[ЮрЛицо] в секции ON вынес за пределы CASE...
Когда будем оптимизировать - несомненно.
Но в общем случае и в отсутствие информации об индексах - возле птиц.А куда вынести за пределы CASE? В WHERE затолкать?
...
Рейтинг: 0 / 0
Вопрос по SQL-запросу
    #39582832
ferzmikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Руслан Дамирович,

Код: 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.
...
WITH
t AS (
  SELECT
    mm.[КодМероприятия],
    tt.[ЮрЛицо],
    tt.[КодТТ],
    mm.[SKU],
    [Дата] = mm.[НачалоМероприятия],
    mm.[КонецМероприятия]
  FROM
    ...
  UNION ALL
  SELECT
    t.[КодМероприятия],
    t.[ЮрЛицо],
    t.[КодТТ],
    t.[SKU],
    [Дата] = DATEADD( DAY, 1, t.[Дата] ),
    t.[КонецМероприятия]
  FROM
    t
  WHERE
    t.[Дата] < t.[КонецМероприятия]
)
...


Получается [Дата] до UNION ALL присваивается один раз. Дальше начинается цикл: [Дата] из функции DATEADD и WHERE берется из последнего [Дата], и далее присваивается новое [Дата] после UNION ALL SELECT. Аналогично по следующей итерации. Верно понимаю?
...
Рейтинг: 0 / 0
Вопрос по SQL-запросу
    #39582997
Руслан Дамирович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, обычное такое CTE с иерархией
...
Рейтинг: 0 / 0
Вопрос по SQL-запросу
    #39583005
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ferzmikkferzmikkЕсли писать так
Код: sql
1.
2.
3.
4.
	where
		@ПромежуточнаяТаблицаДаты.Дата >= @СписокМероприятий.НачалоМероприятия 
		AND
		@ПромежуточнаяТаблицаДаты.Дата <= @СписокМероприятий.КонецМероприятия) AS Таблица


то пишет что нужно объявить скалярные переменные. А если убрать знак @, то пишет, что не удалось привязать составной идентификатор.

Почему так?
Это бы понять еще
Код: sql
1.
[@ПромежуточнаяТаблицаДаты].Дата

Или применять алиасы, что лучше всего
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Вопрос по SQL-запросу
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]