6

我的表是多天和多频道的预定电视节目列表。

SELECT * FROM [Scheduled_Programmes]

Channel   Date          Time     Title
1         2012-09-19    06:00    Family Guy
2         2012-09-19    06:01    CSI Miami
3         2012-09-19    06:20    News
1         2012-09-19    06:30    Heroes
2         2012-09-19    07:01    Spiderman
3         2012-09-19    06:40    Batman
1         2012-09-19    07:30    Micky Mouse
2         2012-09-19    07:31    CSI New York
3         2012-09-19    07:10    Friends
1         2012-09-19    07:55    The Wire
2         2012-09-19    08:00    Dodgeball
3         2012-09-19    07:35    Gossip Girl

我正在尝试创建的结果集是 What's on Now 和 What's on Next。

Let's assume the current datetime is (D/M/Y HH:MM) 19/09/2012 07:15 

所以像:

          Channel 1     Channel 2       Channel 3
NOW       Heroes        Spiderman       Friends  
NEXT      Micky Mous    CSI New York    Gossip Girl

我一直在绞尽脑汁寻找最好的方法来做到这一点,而不必为每个频道硬编码单独的查询。我想我现在已经有了过度思考的阶段,所以如果有人能指出我正确的方向,那就太好了。

谢谢

PS:如果它有所作为,我在 Microsoft SQL Server 2012 上

4

5 回答 5

3

这看起来真的像是你会让你的 GIU 格式化和旋转的东西,但这是我的尝试。

SELECT * FROM (
    SELECT * FROM (
        SELECT X.Status, X.Channel, X.Title FROM (
        SELECT 'NOW' as Status, Channel, Title, RANK() OVER (PARTITION BY Channel ORDER BY Time DESC) RANKED FROM Sceduled_Programs SP
        WHERE DateTime <= '7:15') X
        WHERE X.RANKED = 1
    ) A
    UNION ALL
        SELECT * FROM (
        SELECT Y.Status, Y.Channel, Y.Title FROM (
        SELECT 'NEXT' as Status, Channel, Title, RANK() OVER (PARTITION BY Channel ORDER BY Time ASC) RANKED FROM Sceduled_Programs SP
        WHERE DateTime > '7:15') Y
        WHERE Y.RANKED = 1
    ) B
) DataToPivot
PIVOT (MAX(Title) FOR Channel IN ([1], [2], [3])) AS PivotTable

编辑:我在这里只使用时间,但只是添加日期。您应该真正考虑组合日期和时间列。

Edit2:要添加日期,只需将时间替换为此。甚至应该在日期范围内工作。

WHERE CAST(Date AS DATETIME) + CAST(Time AS DATETIME) > '19/09/2012 07:15'
于 2012-09-18T12:32:46.330 回答
2

这是SQLFiddle 示例如果程序在前一天开始并在当前结束或在当前开始并在第二天结束(对于 NOW 和 NEXT 结果),此查询也很有效。

对于当前日期,只需替换cast('09/19/2012 07:15' as datetime)CURRENT_TIMESTAMP

with T as 
(select channel, title, 
       (date+cast(Time as datetime )) as D_Time 
       from Scheduled_Programmes
)

select nn,
   max(CASE when channel=1 then Title end) as Chanel1, 
   max(CASE when channel=2 then Title end) as Chanel2,
   max(CASE when channel=3 then Title end) as Chanel3


from
(
select 'NOW' nn,Channel,Title,D_time,
    row_number() over (PARTITION by channel 
                      order by D_time desc) rn 
    from T
    where D_time<=cast('09/19/2012 07:15' as datetime)
union
select 'NEXT'nn,Channel,Title,D_time,
     row_number() over (PARTITION by channel 
                        order by D_time asc) rn 
     from T
     where D_time>cast('09/19/2012 07:15' as datetime)
) ATable where rn=1
group by nn
order by nn desc;
于 2012-09-18T13:16:55.780 回答
0
select distinct Channel
, (
select top 2 Title from 
        (
         select Title
         from [Scheduled_Programmes] s
         where s.Channel = o.Channel
         and Date >='2012-09-19' and Time >='07:15' 
         group by Channel
         order by Date, Time desc
        ) x
) as Prog
from [Scheduled_Programmes] o

我没有尝试过(由于此时 SQL Server 不可用),但这应该可以。

于 2012-09-18T12:09:46.203 回答
0

要获取数据和交叉表,请使用以下内容。您可以在第一次选择中重命名通道列,但您必须在数据透视列表中指定有效通道。

Nb 可以通过将日期和时间字段组合到单个日期时间字段来简化代码。

declare @current_date datetime = '20120919 07:15'

select *
from (
  select whenon, a1.channel, title from (
  select a.channel, MAX(CAST(Date AS DATETIME) + CAST(Time AS DATETIME)) as DateTime, 'now' as whenon
  from Scheduled_Programmes a
  join (
    select channel, MIN(CAST(Date AS DATETIME) + CAST(Time AS DATETIME)) as NextTime
    from Scheduled_Programmes 
    where CAST(Date AS DATETIME) + CAST(Time AS DATETIME) > @current_date
    group by channel
  ) b on a.channel = b.channel and CAST(Date AS DATETIME) + CAST(Time AS DATETIME) < NextTime
  group by a.channel
  union
  select channel, MIN(CAST(Date AS DATETIME) + CAST(Time AS DATETIME)), 'next' from Scheduled_Programmes where CAST(Date AS DATETIME) + CAST(Time AS DATETIME) > @current_date
  group by channel

  ) a1
  join Scheduled_Programmes b1 on a1.channel = b1.channel and a1.DateTime = CAST(Date AS DATETIME) + CAST(Time AS DATETIME)
) sub
pivot (max(title) for channel in ([1], [2], [3])) pivottable
order by whenon desc
于 2012-09-18T12:24:13.670 回答
0

另一个可能的选项 - 计算时间差并获取最小的 +ve 值(下一个)和最小的 -ve 值(现在) - 假设 DATE 和 TIME 类型字段,还返回自开始/直到开始的分钟数。

;with T(Channel, Date, Time, Title, delta) as (
select 
    *,
    datediff(minute, '19 sep 2012 07:15:00', dateadd(day, datediff(day, 0, date), cast(time as datetime2)))
from 
    Scheduled_Programmes
)
select 
case when T.delta >= 0 then 'Next' else 'Now' end,
T.* 
from T
inner join (
    select
        channel,
        min(case when delta > 0 then delta end) as starts_in,
        max(case when delta < 0 then delta end) as started
    from t
    group by channel
) T2
    on T.Channel = T2.Channel and (t.delta = T2.starts_in or t.delta=T2.started)
order by Channel, delta 
于 2012-09-18T13:53:24.717 回答