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

Есть поле ТипСвязиТТ и имеет 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
11.01.2018, 14:29
    #39582525
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по SQL-запросу
По-моему, во второй таблице упущено поле SKU... без него не очень срастается.
...
Рейтинг: 0 / 0
11.01.2018, 14:51
    #39582543
Руслан Дамирович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по 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.
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
11.01.2018, 14:59
    #39582557
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по SQL-запросу
AkinaПо-моему, во второй таблице упущено поле SKU... без него не очень срастается.
Вторая таблица отображает список ТТ и не имеет связи с SKU. Таблица отображает какая именно ТТ относится в группе для первого признака и в какой группе для второго признака, и какое юридическое лицо. Потом с помощью поля "Тип связи" и "Код ТТ" из первой таблицы вытаскиваются коды ТТ. Поле "Код ТТ" из первой таблицы, это не только код ТТ, но и Коды полей "ПервыйПризнакОбъединения" "ВторойПризнакОбъединения".
...
Рейтинг: 0 / 0
11.01.2018, 16:35
    #39582670
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по SQL-запросу
Руслан Дамирович , я бы условие tt.[ЮрЛицо] = mm.[ЮрЛицо] в секции ON вынес за пределы CASE...
...
Рейтинг: 0 / 0
11.01.2018, 18:30
    #39582744
Руслан Дамирович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по SQL-запросу
Akina Руслан Дамирович , я бы условие tt.[ЮрЛицо] = mm.[ЮрЛицо] в секции ON вынес за пределы CASE...
Когда будем оптимизировать - несомненно.
Но в общем случае и в отсутствие информации об индексах - возле птиц.
...
Рейтинг: 0 / 0
11.01.2018, 20:07
    #39582796
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по SQL-запросу
Руслан Дамирович,

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

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

Почему так?
Это бы понять еще
...
Рейтинг: 0 / 0
11.01.2018, 20:53
    #39582820
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по SQL-запросу
Руслан ДамировичAkina Руслан Дамирович , я бы условие tt.[ЮрЛицо] = mm.[ЮрЛицо] в секции ON вынес за пределы CASE...
Когда будем оптимизировать - несомненно.
Но в общем случае и в отсутствие информации об индексах - возле птиц.А куда вынести за пределы CASE? В WHERE затолкать?
...
Рейтинг: 0 / 0
11.01.2018, 21:11
    #39582832
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по 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.
...
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
12.01.2018, 09:01
    #39582997
Руслан Дамирович
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по SQL-запросу
Да, обычное такое CTE с иерархией
...
Рейтинг: 0 / 0
12.01.2018, 09:12
    #39583005
iap
iap
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вопрос по SQL-запросу
ferzmikkferzmikkЕсли писать так
Код: sql
1.
2.
3.
4.
	where
		@ПромежуточнаяТаблицаДаты.Дата >= @СписокМероприятий.НачалоМероприятия 
		AND
		@ПромежуточнаяТаблицаДаты.Дата <= @СписокМероприятий.КонецМероприятия) AS Таблица


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

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

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


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