将这两个单独的SQL语句合并为一个查询

时间:2014-08-26 21:21:11

标签: sql sql-server

我有以下两个SQL查询,除了最后的WHERE子句之外几乎都是相同的,有没有办法将这两个查询合并为一个?我尝试编写子查询,但我尝试过没有尝试过。第一个查询生成最近14天数据的平均值列表,第二个查询使用过去7天的值生成列表。

SELECT 
   report.report_group  ,
   report.business_name ,
   round(avg( datediff(mi,price.price_date,price.valid_date) ),0) average_minutes
FROM archive.report     AS report
JOIN archive.allocation AS allocation ON report.book_name       = allocation.book
JOIN archive.position   AS position   ON position.allocation_id = allocation_id
JOIN archive.price      AS price      ON price.position_id      = position.position_id
WHERE price.price_date < CONVERT(VARCHAR(10), dateadd(day,-14,getdate()) , 102 )
GROUP BY report_group ,
         business_name

......第二个是:

SELECT 
   report.report_group  ,
   report.business_name ,
   round(avg( datediff(mi,price.price_date,price.valid_date) ),0) average_minutes
FROM archive.report     AS report
JOIN archive.allocation AS allocation ON report.book_name       = allocation.book
JOIN archive.position   AS position   ON position.allocation_id = allocation_id
JOIN archive.price      AS price      ON price.position_id      = position.position_id
WHERE price.price_date < CONVERT(VARCHAR(10), dateadd(day,-14,getdate()) , 102 )
GROUP BY report_group  ,
         business_name

5 个答案:

答案 0 :(得分:0)

我认为您打算在底层查询中添加-7? (我把第二个改为-7,下面)。此外,您在转换函数后缺少右括号。

下面的查询将您当前的第三列拆分为2列,一列用于14列,一列用于7.它比运行几乎相同的相同查询两次并使用union连接更有效。它使用条件聚合来显示最后14个和最后7个的平均值.WHERE子句表示最后7个,因为在这种情况下它需要是下边界。

SELECT report.report_group,
       report.business_name,
       round(avg(case when price.price_date < CONVERT(VARCHAR(10), dateadd(day, -14, getdate()), 102) then
                  datediff(mi, price.price_date, price.valid_date) end), 0) average_minutes_14_dy,
       round(avg(case when price.price_date < CONVERT(VARCHAR(10), dateadd(day, -7, getdate()), 102) then
                  datediff(mi, price.price_date, price.valid_date) end), 0) average_minutes_7_dy
  FROM archive.report AS report
 INNER JOIN archive.allocation AS allocation
    ON report.book_name = allocation.book
 INNER JOIN archive.position AS position
    ON position.allocation_id = allocation_id
 INNER JOIN archive.price AS price
    ON price.position_id = position.position_id
 WHERE price.price_date <
       CONVERT(VARCHAR(10), dateadd(day, -7, getdate()), 102)
 GROUP BY report_group, business_name

答案 1 :(得分:0)

我会坚持使用OR:

SELECT report.report_group,
   report.business_name,
   round(avg(datediff(mi, price.price_date, price.valid_date)), 0) average_minutes
FROM archive.report AS report
INNER JOIN archive.allocation AS allocation
ON report.book_name = allocation.book
INNER JOIN archive.position AS position
ON position.allocation_id = allocation_id
INNER JOIN archive.price AS price
ON price.position_id = position.position_id
WHERE price.price_date < CONVERT(VARCHAR(10), dateadd(day, -14, getdate()), 102) 
OR price.price_date <     CONVERT(VARCHAR(10), dateadd(day, -7, getdate(), 102))
GROUP BY report_group, business_name

答案 2 :(得分:0)

这样的事情?

select
        report_group, business_name, days,
        round(avg(mi_diff), 0) average_diff
from 
(       
    SELECT 
            r.report_group, r.business_name, 
            case when pr.price_date < CONVERT (VARCHAR (10), dateadd(day, -7, getdate()), 102) then 7 else 14 end as days,
            datediff(mi, pr.price_date, pr.valid_date) as mi_diff
    FROM   
            archive.report r
           INNER JOIN archive.allocation a ON r.book_name = a.book
           INNER JOIN archive.position po ON po.allocation_id = allocation_id
           INNER JOIN archive.price pr ON pr.position_id = po.position_id
    WHERE 
            pr.price_date < CONVERT (VARCHAR (10), dateadd(day, -14, getdate()), 102)
) d
GROUP BY 
        report_group, business_name, days

答案 3 :(得分:0)

“Where”子句中的“Or”可能是最有意义的,但如果你真的想在同一个表中显示两个结果集,那么你可以使用“union all”。现在,如果你想过滤出2个查询之间的重复数据(即一个查询与另一个查询的结果相同,你只想显示一次),那么使用“union”

继承人工会:

SELECT report.report_group, report.business_name, round(avg(datediff(mi, price.price_date, price.valid_date)), 0) average_minutes
FROM   archive.report AS report
   INNER JOIN archive.allocation AS allocation ON report.book_name = allocation.book
   INNER JOIN archive.position AS position ON position.allocation_id = allocation_id
   INNER JOIN archive.price AS price ON price.position_id = position.position_id
WHERE price.price_date < CONVERT (VARCHAR (10), dateadd(day, -14, getdate(), 102)
GROUP BY report_group, business_name

UNION ALL

SELECT report.report_group, report.business_name, round(avg(datediff(mi, price.price_date, price.valid_date)), 0) average_minutes
FROM   archive.report AS report
   INNER JOIN archive.allocation AS allocation ON report.book_name = allocation.book
   INNER JOIN archive.position AS position ON position.allocation_id = allocation_id
   INNER JOIN archive.price AS price ON price.position_id = position.position_id
WHERE price.price_date < CONVERT (VARCHAR (10), dateadd(day, -14, getdate(), 102)
GROUP BY report_group, business_name

答案 4 :(得分:0)

在[standard] SQL中,所有聚合函数都保存count() ignore null。如果您碰巧知道这一点,那么您的查询似乎不会比这样的事情困难得多:

select report_group  = rpt.report_group  ,
       business_name = rpt.business_name ,
       mean_14       = round(avg(
                         case 
                         when prc.price_date < convert(varchar(10),dateadd(day,-14,getdate()),102)
                         then datediff(mi,prc.price_date,prc.valid_date)
                         end
                       ),0) ,
       mean_7        = round(avg(
                         case
                         when prc.price_date < convert(varchar(10),dateadd(day,-7,getdate()),102)
                         then datediff(mi,prc.price_date,prc.valid_date)
                         end
                       ),0) ,
from archive.report     rpt
join archive.allocation alc on alc.book          = rpt.book_name
join archive.position   pos on pos.allocation_id = alc.allocation_id
join archive.price      prc on pre.position_id   = pos.position_id
group by rpt.report_group ,
         rpt.business_name