2016-02-07 5 views
2

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

+----------+------------+-----------+-------------+------------+ 
| EventId | EventName | Country | Attendance | EventDate | 
+----------+------------+-----------+-------------+------------+ 
|  1 | Soccer1 | Australia |  12000 | 2015-01-01 | 
|  2 | Soccer2 | Mexico |  35999 | 2016-02-02 | 
|  3 | Soccer3 | Australia |  13999 | 2015-03-22 | 
|  4 | Football1 | Japan  |  13555 | 2003-11-12 | 
|  5 | Football2 | Japan  |  12222 | 2004-01-01 | 
|  6 | Football3 | Canada |  13444 | 2003-02-23 | 
|  7 | Tennis1 | America |  10000 | 2014-01-02 | 
|  8 | Tennis2 | America |  12111 | 2015-10-01 | 
+----------+------------+-----------+-------------+------------+ 

CREATE TABLE [dbo].[Sports](
    [EventId] [int] NULL, 
    [EventName] [varchar](50) NULL, 
    [Country] [varchar](50) NULL, 
    [Attendance] [int] NULL, 
    [EventDate] [date] NULL 
INSERT [dbo].[Sports] ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (1, N'Soccer1', N'Australia', 12000, CAST(N'2015-01-01' AS Date)) 
INSERT [dbo].[Sports] ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (2, N'Soccer2', N'Mexico', 35999, CAST(N'2016-02-02' AS Date)) 
INSERT [dbo].[Sports] ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (3, N'Soccer3', N'Australia', 13999, CAST(N'2015-03-22' AS Date)) 
INSERT [dbo].[Sports] ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (4, N'Football1', N'Japan', 13555, CAST(N'2003-11-12' AS Date)) 
INSERT [dbo].[Sports] ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (5, N'Football2', N'Japan', 12222, CAST(N'2004-01-01' AS Date)) 
INSERT [dbo].[Sports] ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (6, N'Football3', N'Canada', 13444, CAST(N'2003-02-23' AS Date)) 
INSERT [dbo].[Sports] ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (7, N'Tennis1', N'America', 10000, CAST(N'2014-01-02' AS Date)) 
INSERT [dbo].[Sports] ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (8, N'Tennis2', N'America', 12111, CAST(N'2015-10-01' AS Date)) 

Так что я создал КТР, чтобы выяснить, какие страны провели мероприятие несколько раз, а затем пытался использовать функцию lead заказанной eventdate, чтобы увидеть, если последняя дата была выше посещаемость.

Но когда эти условия выполнены, я хочу отобразить и строку с более высокой посещаемостью, и строку с предыдущим событием. Моя попытка показывает только строку с самой последней датой.

with t as (
select EventId, EventName, Country, Attendance, CONVERT(VARCHAR(11),EventDate,106) as Date 
from Sports 
where Country in (select Country from Sports group by Country having count(*)>=2) 
), 
s as (

select *, LEAD(Attendance) over (partition by Country order by cast([Date] as datetime) desc) as PrevAttendance 
from t 
) 

select EventName, Country, Attendance, Date 
from s 
where Attendance > PrevAttendance 

Так что мой вопрос тоже, в общем, как вы выполняете операции на каждом разделе/​​окна, установленного в SQL Server 2014. Поскольку в этом примере, если бы было гораздо больше событий в стране, я мог бы также хотеть чтобы проверить, является ли последнее посещение, по крайней мере, больше, чем любое предыдущее, а не только самое непосредственное предыдущее событие.

Надеюсь, это имеет смысл, заблаговременно за помощь.

Так что мой ожидаемый результат для этой таблицы будет выглядеть следующим образом:

+----------+------------+-----------+-------------+------------+ 
| EventId | EventName | Country | Attendance | EventDate | 
+----------+------------+-----------+-------------+------------+ 
|  1 | Soccer1 | Australia |  12000 | 2015-01-01 | 
|  3 | Soccer3 | Australia |  13999 | 2015-03-22 | 
|  7 | Tennis1 | America |  10000 | 2014-01-02 | 
|  8 | Tennis2 | America |  12111 | 2015-10-01 | 
+----------+------------+-----------+-------------+------------+ 
+0

почему Канада не входит в группу? – TheGameiswar

+0

Вопрос, в общем, слишком широк. Вы должны уточнить вопрос, который задают. –

+0

Извините, я получил это ... если это для меня – TheGameiswar

ответ

0

ROW_NUMBER Используйте, чтобы получить две последние строки.

with 
cte as (
    select *, 
     lead(Attendance) -- next row 
     over (partition by Country 
      order by EventDate desc) as PrevAttendance, 
     lag(Attendance) -- previous row 
     over (partition by Country 
      order by EventDate desc) as NextAttendance, 
     ROW_NUMBER() 
     over (partition by Country 
      order by EventDate desc) as rn 

from sports 
) 
select * 
from cte 
    -- only the last two rows 
    -- when last row's value is greater than previous row's value 
where (rn = 1 and Attendance > PrevAttendance) 
    or (rn = 2 and Attendance < NextAttendance) 

Используйте кумулятивный MIN, чтобы найти минимальное значение за все предыдущие строки:

MIN(Attendance) 
over (partition by Country 
     order by EventDate desc 
      -- all rows before the current row 
     rows between unbounded preceding and 1 preceding) 
1
SET NOCOUNT ON; 
CREATE TABLE #sports(
    [EventId] [int] NULL, 
    [EventName] [varchar](50) NULL, 
    [Country] [varchar](50) NULL, 
    [Attendance] [int] NULL, 
    [EventDate] [date] NULL 
); 
INSERT INTO #sports ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (1, N'Soccer1', N'Australia', 12000, CAST(N'2015-01-01' AS Date)) 
INSERT INTO #sports ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (2, N'Soccer2', N'Mexico', 35999, CAST(N'2016-02-02' AS Date)) 
INSERT INTO #sports ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (3, N'Soccer3', N'Australia', 13999, CAST(N'2015-03-22' AS Date)) 
INSERT INTO #sports ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (4, N'Football1', N'Japan', 13555, CAST(N'2003-11-12' AS Date)) 
INSERT INTO #sports ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (5, N'Football2', N'Japan', 12222, CAST(N'2004-01-01' AS Date)) 
INSERT INTO #sports ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (6, N'Football3', N'Canada', 13444, CAST(N'2003-02-23' AS Date)) 
INSERT INTO #sports ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (7, N'Tennis1', N'America', 10000, CAST(N'2014-01-02' AS Date)) 
INSERT INTO #sports ([EventId], [EventName], [Country], [Attendance], [EventDate]) VALUES (8, N'Tennis2', N'America', 12111, CAST(N'2015-10-01' AS Date)) 


;WITH cte AS (
    SELECT 
     *, 
     pat=CASE 
      WHEN LAG(Attendance) OVER (PARTITION BY Country ORDER BY EventId)IS NULL THEN 0 
      WHEN Attendance<LAG(Attendance) OVER (PARTITION BY Country ORDER BY EventId) THEN 0 
      ELSE 1 
     END, 
     patid=LAG(EventId) OVER (PARTITION BY Country ORDER BY EventId) 
    FROM 
     #sports 
) 
SELECT 
    [EventId], [EventName], [Country], [Attendance], [EventDate] 
FROM 
    cte 
WHERE 
    pat=1 
UNION 
SELECT 
    inn.[EventId], inn.[EventName], inn.[Country], inn.[Attendance], inn.[EventDate] 
FROM 
    cte AS ou 
    INNER JOIN cte AS inn ON 
     inn.EventId=ou.patid 
WHERE 
    ou.pat=1 
ORDER BY 
    EventId; 

DROP TABLE #sports; 

Результаты:

+---------+-----------+-----------+------------+------------+ 
| EventId | EventName | Country | Attendance | EventDate | 
+---------+-----------+-----------+------------+------------+ 
|  1 | Soccer1 | Australia |  12000 | 2015-01-01 | 
|  3 | Soccer3 | Australia |  13999 | 2015-03-22 | 
|  7 | Tennis1 | America |  10000 | 2014-01-02 | 
|  8 | Tennis2 | America |  12111 | 2015-10-01 | 
+---------+-----------+-----------+------------+------------+ 
+0

UNION есть, чтобы отфильтровать двойники в случаях, когда есть 3 события, каждый из которых увеличивается на посещаемость. –

+0

Где вы проверяете, что посещаемость увеличилась для страны * в том же виде спорта *? Образцы данных в настоящее время работают в вашу пользу, даже если вы игнорируете эту деталь, потому что ни одна страна не играет в двух разных видах спорта. Но согласно OP, это должно сравниваться по тому же событию, возвращающемуся в ту же страну. – mellamokb

+0

@mellamokb Нет колонки, в которой есть только спорт. Если бы я изменил запрос и разделил на EventName, результаты больше не соответствовали ожидаемому результату, который OP имеет в своем вопросе (результаты будут пустыми). В любом случае, если есть такое дополнительное поле для разбиения на разделы, легко добавить это к запросу. –

Смежные вопросы