交叉申请总计

时间:2015-07-09 13:35:23

标签: sql sql-server cross-apply

我有2个表,需要从表1中获取每行的总数作为新列

  

表格程序:

AIR_DATE              START_TIME    END_TIME
-------------------------------------------
1/26/2015 12:00:00 AM   27000000    28800000
1/26/2015 12:00:00 AM   28800000    32400000
1/26/2015 12:00:00 AM   34200000    34280000
  

表评级:

IMPRESSION_DATE   IMP_START_TIME    IMP_END_TIME  HH    F2_5  IMP_STATUS
--------------------------------------------------------------------
1/26/2015 12:00:00 AM   27000000    27899000      8685  4415   F
1/26/2015 12:00:00 AM   27900000    28799000      8690  4421   F 
1/26/2015 12:00:00 AM   28800000    29699000      9900  4410   F
1/26/2015 12:00:00 AM   29700000    30599000      9906  4414   F
1/26/2015 12:00:00 AM   30600000    31499000      6925  2580   F
1/26/2015 12:00:00 AM   31500000    32399000      6928  2588   F
1/26/2015 12:00:00 AM   32400000    33299000      9988  17     F
1/26/2015 12:00:00 AM   33300000    34199000      9998  19     F
1/26/2015 12:00:00 AM   34200000    35099000       781  2457   F

我正在寻找如何将目标结果集设为:

AIR_DATE    START_TIME  END_TIME  IMP_DATE IMP_START_TIME  IMP_END_TIME  HH_F  F2_5_F
1/26/2015   27000000    28800000  1/26/2015      27000000   28799000  8687.5   4418
1/26/2015   28800000    30600000  1/26/2015     28800000    30599000 8414.75   3498
1/26/2015   34200000    34280000  1/26/2015     34200000    35099000     781   2457
  

我的查询示例,但它没有帮助我:)

SELECT *
FROM PROGRAMS as P
    CROSS APPLY (
           SELECT 
              MIN(CASE WHEN R.IMP_STATUS = 'F' THEN IMP_START_TIME END) as IMP_START_TIME,
              MAX(CASE WHEN R.IMP_STATUS = 'F' THEN IMP_END_TIME END) as IMP_END_TIME,

              AVG(CASE WHEN R.IMP_STATUS = 'F' THEN HH END) as HH_F,
              AVG(CASE WHEN R.IMP_STATUS = 'F' THEN F2_5 END) as F2_5_F
            FROM RATINGS as R  
            WHERE R.IMPRESSION_DATE = P.AIR_DATE 
              AND R.IMP_START_TIME <= P.START_TIME 
              AND P.END_TIME <= R.IMP_END_TIME) as R

RDBS :MS SQL SERVER 2008 R2 SQL Fiddler示例: http://sqlfiddle.com/#!3/68fa5/2

2 个答案:

答案 0 :(得分:2)

如果您将交叉申请中的时间限制条件更改为:

WHERE R.IMPRESSION_DATE = P.AIR_DATE 
  AND 
  (
    (R.IMP_START_TIME >= P.START_TIME AND R.IMP_END_TIME <= P.END_TIME) 
    OR
    (R.IMP_START_TIME <= P.START_TIME AND R.IMP_END_TIME >= P.END_TIME)
  )

你会得到如下结果:

AIR_DATE    START_TIME  END_TIME    IMP_START_TIME  IMP_END_TIME        HH_F    F2_5_F
2015-01-26 00:00:00.000 27000000    28800000    27000000    28799000    8687    4418
2015-01-26 00:00:00.000 28800000    32400000    28800000    32399000    8414    3498
2015-01-26 00:00:00.000 34200000    34280000    34200000    35099000    781     2457

看起来是正确的:)

答案 1 :(得分:0)

哪个SQL Server版本?自2008年以来,您可以将OVER与MIN,MAX和AVG(https://msdn.microsoft.com/en-us/library/ms189461.aspx

等聚合函数一起使用

编辑:添加例子 也许你从CTE开始,在最后的SELECT中做SELECT MIN/MAX/AVG(x) OVER()

WITH myCTE AS
(
    SELECT pr.AIR_DATE,pr.START_TIME,pr.END_TIME
    FROM Programs AS pr
    INNER JOIN Ratings AS rt ON pr.AIR_DATE =rt.IMPRESSION_DATE
                            AND pr.START_TIME=rt.IMP_START_TIME
                            AND pr.END_TIME <= rt.IMP_END_TIME 
)
SELECT * FROM myCTE