Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Склеить строки.  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Привет.
Подскажите пожалуйста как такую задачу лучше всего решить.

Имеются 3 таблицы с "событиями".


Tab1
DateCreate
01.01.2003
02.01.2003
01.02.2003
01.05.2003
02.05.2003



Tab2
DateCreate
01.02.2003
02.02.2003
01.03.2003
01.06.2003
02.06.2003


Нужно просуммировать количество событий за период в каждой таблице и вывести результа. Причем нужно строки с совпадающими периодами дат объединить:

Result
MonthDateCreate Event1Count Event2Count
01.2003 20
02.2003 12
03.2003 01
05.2003 20
06.2003 02


Я понимаю как сделать первую часть:
SELECT DATEPART(month,DateCreated), count(*)
FROM Tab1 t
where t.DateCreated < GETDATE()
group by DATEPART(month,DateCreated)


SELECT DATEPART(month,DateCreated), count(*)
FROM Tab2 t
where t.DateCreated < GETDATE()
group by DATEPART(month,DateCreated)



А вот как объединить результаты, чтобы они были в одной строке ?
19 май 16, 17:47    [19195114]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
buser
Member

Откуда: Санкт-Петербург
Сообщений: 4537
ProBiotek, union
19 май 16, 17:51    [19195133]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2421
ProBiotek,

у вас не получается сделать join?

select *
from (подзапрос1) a
join (подзапрос2) a1 on a.MonthDateCreate = a1.MonthDateCreate
19 май 16, 17:51    [19195135]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
WarAnt,

join не пойдёт скорее всего. FULL OUTER JOIN
19 май 16, 17:53    [19195145]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
TaPaK,

Точно ! Full Join ! Это решение.
19 май 16, 17:58    [19195163]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Подскажите еще пожалуйста. Как группировать И по Месяцу и по Году.
Можно же только DATEPART(YEAR,DateCreated) или DATEPART(Month,DateCreated).

Нужно чтобы в итоговой выборке выводить Месяц.Год.
19 май 16, 18:01    [19195174]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2421
TaPaK
WarAnt,

join не пойдёт скорее всего. FULL OUTER JOIN


а где я написал что join должен быть обязательно inner ?
19 май 16, 18:03    [19195180]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2421
ProBiotek
Подскажите еще пожалуйста. Как группировать И по Месяцу и по Году.
Можно же только DATEPART(YEAR,DateCreated) или DATEPART(Month,DateCreated).

Нужно чтобы в итоговой выборке выводить Месяц.Год.


format используйте либо convert если версия сервера не позволяет
19 май 16, 18:04    [19195184]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
WarAnt,

А как это поможет ?
Как применить Format, чтобы по нему группировать, а после склеивания двух запросов иметь доступ к Месяцу и Году отдельно. Чтобы их вывести в таблице в отдельные два поля.
19 май 16, 18:07    [19195192]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
Я сейчас сделал так.

select 
   CASE 
      WHEN s1.dat is not null  THEN s1.dat
      else s2.dat
   END as dat,
   s1.counts s1_counts, s2.counts s2_counts


from 

(
SELECT DATEPART(month,DateCreated) dat, count(*) counts
FROM Tab1 t

where t.DateCreated < GETDATE()
group by DATEPART(month,DateCreated), DATEPART(YEAR,DateCreated)
) s1

full join 
(
SELECT DATEPART(month,DateCreated) dat, count(*) counts
FROM Tab2 t

where t.DateCreated < GETDATE()
group by DATEPART(month,DateCreated), DATEPART(YEAR,DateCreated)  
) s2  on s1.dat = s2.dat




результат запроса такой:

dat s1_counts s2_counts
2 NULL 1
3 1 1
4 1 NULL
5 1 1


Но тут dat - это месяц.
А нужно чтобы был и месяц и год, ну и чтобы они были атомарными.
19 май 16, 18:09    [19195202]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
StarikNavy
Member

Откуда: Москва
Сообщений: 2396
ProBiotek,

 DATEPART(yy,DateCreated) yy, DATEPART(month,DateCreated) dat,
19 май 16, 18:12    [19195204]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
buser
Member

Откуда: Санкт-Петербург
Сообщений: 4537
ProBiotek,
+
select FORMAT(xyz.DateCreated, 'MM.yyyy', 'Ru-ru') /*month(xyz.DateCreated), year(xyz.DateCreated)*/ , sum(case EventSource when 1 then 1 else 0 end),  sum(case EventSource when 2 then 1 else 0 end)
from
(
SELECT t.DateCreated, 1 as EventSource
FROM @t1 t
UNION ALL
SELECT t.DateCreated, 2 as EventSource
FROM @t2 t
) xyz
where xyz.DateCreated <  GETDATE()
group by FORMAT(xyz.DateCreated, 'MM.yyyy', 'Ru-ru') /*month(xyz.DateCreated), year(xyz.DateCreated)*/
19 май 16, 18:12    [19195206]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
StarikNavy,

Точно ! Получилось. Спасибо


select 
   CASE 
      WHEN s1.mm is not null  THEN s1.mm
      else s2.mm
   END as mm,
   CASE 
      --проверяем s1.mm, чтобы не получилось, что месяц берется от одной даты, а год от другой. Хотя не уверен может ли тут оказаться yy равен null. Вроде нет, но решил перестраховаться.
      WHEN s1.mm is not null  THEN s1.yy
      else s2.yy
   END as mm,
   s1.counts s1_counts, s2.counts s2_counts


from 

(
SELECT DATEPART(month,DateCreated) mm, DATEPART(YEAR,DateCreated) yy, count(*) counts
FROM [RT.Learn_1].[Forum].[Topic] t

where t.DateCreated < GETDATE()
group by DATEPART(month,DateCreated), DATEPART(YEAR,DateCreated), DATEPART(month,DateCreated)+DATEPART(YEAR,DateCreated)
) s1

full join 
(
SELECT DATEPART(month,DateCreated) mm, DATEPART(YEAR,DateCreated) yy, count(*) counts
FROM [RT.Learn_1].[Forum].[Message] t

where t.DateCreated < GETDATE()
group by DATEPART(month,DateCreated), DATEPART(YEAR,DateCreated)  
) s2  on s1.mm = s2.mm and s1.yy = s2.yy
19 май 16, 18:16    [19195219]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
buser,

Но в Вашем варианте не удобно то, то месяц и год не атомарны. Не удобно потом с ними работать по отдельности. Придется делать обратную операцию для FORMAT - т.е. парсить.
19 май 16, 18:23    [19195246]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
buser
Member

Откуда: Санкт-Петербург
Сообщений: 4537
ProBiotek, раскоментируйте строки - формат уберите...
19 май 16, 18:25    [19195256]     Ответить | Цитировать Сообщить модератору
 Re: Склеить строки.  [new]
ProBiotek
Member

Откуда: Moscow
Сообщений: 907
buser,

Действительно.
Ваш вариант весьма компактен. Не то, что у меня получилось.

И план запроса вроде меньше гораздо!
19 май 16, 18:36    [19195297]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить