2012-09-18 22 views
6

我的表格是多天和頻道的預定電視節目列表。現在和下一個電視節目信息SQL查詢

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 

我試圖創建的結果集是什麼在現在和接下來是什麼。

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

回答

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 

編輯: 我只使用一次來這裏,但只是添加日期。您應該考慮將日期和時間列結合起來。

編輯2: 要添加日期只需替換時間比較與此。甚至應該在日期範圍內工作。

WHERE CAST(Date AS DATETIME) + CAST(Time AS DATETIME) > '19/09/2012 07:15' 
+0

太棒了!非常感謝!我確實有一個合併的日期/時間列,但是這是針對「真實」傳輸時間,而不是我在此處使用的電視指南樣式時間/日期。 (例如:18:00:00 vs 18:02:13)另外,我同意其中一些可以在GUI中完成,但我知道它可以在SQL中完成,並且讓我發瘋。謝謝 – pugu

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不可用),但此應該管用。

+0

你不能'在標量上下文菜單中選擇頂2' – Andomar

+0

謝謝,這也沒有用含標題某種骨料出想要的順序。 – pugu

0

要獲取數據和交叉表,請使用以下內容。您可以在第一次選擇時重命名頻道列,但您必須在數據透視表中指定有效頻道。

N.b.通過將日期和時間字段組合到單個日期時間字段,可以簡化代碼。

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 
+0

謝謝,我也會試驗這個代碼。 – pugu

+0

乾杯,這在所有情況下的作品只是看起來有點醜,因爲我沒有CTE或RANK()出於某種原因! –

2

這是SQLFiddle example如果一個程序在前一天開始,並在當前結束或在當前開始並在第二天(對於NOW和NEXT結果)結束,該查詢也適用。

對於當前的日期正好與CURRENT_TIMESTAMP替換cast('09/19/2012 07:15' as datetime)

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; 
+0

上面的Magnuses例子不能處理'next'程序,因爲它在日期邊界上,因爲我已經實現了它,所以會進一步修補並查閱你的代碼。 – pugu

0

另一種可能的選擇 - 計算時間差&取最小+已經值(NEXT)和最小-ve值(現在) - 假定日期& 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