将具有不同where和不同分组的两个查询合并为1

时间:2014-09-19 13:32:02

标签: sql tsql stored-procedures

抱歉,我之前问了这个问题并得到了一些好的答案,但后来我意识到我在查询中犯了错误,如果我在原帖中更改了可能使答案无效的问题,那么我就发帖了再次使用正确的查询,请原谅我,我希望这是可以接受的。

DECLARE @Temp TABLE
(MeasureDate, col1, col2, type)

INSERT INTO @Temp
SELECT  MeasureDate, col1, col2, 1
FROM Table1
WHERE Col3 = 1

INSERT INTO @Temp
SELECT  MeasureDate, col1, col2, 3
FROM Table1
WHERE Col3 = 1
AND Col4 = 7000

SELECT SUM(col1) / SUM(col2) AS Percentage, MeasureDate, Type
FROM @Temp
GROUP BY MeasureDate, Type

我在临时表中进行了两次插入,第二次插入有一个额外的WHERE但是相同的列同一个表,但是类型不同,然后我在临时表上执行SUM(col1)/ SUM(col2)以返回我需要的结果每个MeasureDate和类型。有没有办法合并所有这些插入并选择一个语句所以我不使用临时表并从表1中进行一次选择?或者即使我仍然需要临时表,将选择合并为一个选择而不是两个单独的选择?存储过程工作正常,只是寻找缩短它的方法。

感谢。

3 个答案:

答案 0 :(得分:3)

当然可以。我可能会首先使用UNION ALL合并插入的两个查询(此UNION的变体不会删除重复项),包含在CTE中,您可以从中执行最终查询:

WITH MeasureData(MeasureDate, col1, col2, type) AS (
    SELECT  MeasureDate, col1, col2, 1
    FROM Table1
    WHERE Col3 = 1
    UNION ALL
    SELECT  MeasureDate, col1, col2, 3
    FROM Table1
    WHERE Col3 = 1
    AND Col4 = 7000
)
SELECT SUM(col1) / SUM(col2) AS Percentage, MeasureDate, Type
FROM MeasureData
GROUP BY MeasureDate, Type

那就是它,没有更多的表变量或插入语句。

答案 1 :(得分:3)

不需要UNION,您可以使用CASE声明处理此问题:

SELECT SUM(col1) / SUM(col2) AS Percentage, MeasureDate, Type
FROM (
    SELECT  MeasureDate, col1, col2, case when Col4 = 7000 then 3 else 1 end type
    FROM Table1
    WHERE Col3 = 1
) t
GROUP BY MeasureDate, Type

正如戈登正确指出的那样,对于Type = 1,此查询不会产生相同的结果。这是Gordon的优秀答案的变体,使用CROSS JOINIF逻辑可以更容易直观地理解:

SELECT T1.MeasureDate, 
  T.Type, 
  SUM(IF(T.Type=1,Col1,IF(T.Type=3 AND T1.Col4=7000,T1.Col1,0))) / 
  SUM(IF(T.Type=1,Col2,IF(T.Type=3 AND T1.Col4=7000,T1.Col2,0))) AS Percentage
FROM Table1 T1
  CROSS JOIN (SELECT 1 Type UNION SELECT 3) T
WHERE T1.Col3 = 1
GROUP BY T1.MeasureDate, T.Type

答案 2 :(得分:2)

您的方法是重复计算col3 = 1col4 = 7000的情况。这是一种考虑到这一点的方法,整个表上没有union

select t.type, SUM(t1.col1) / SUM(t1.col2) AS Percentage, t1.MeasureDate, t.Type
from table1 t1 join
     (select 1 as type union all
      select 3 as type
     ) t
     on t.type = 1 or t1.col4 = 7000
where t1.col3 = 1
group by measuredate, type;