【问题标题】:Merging results of a query合并查询结果
【发布时间】:2013-10-16 14:58:52
【问题描述】:

我知道我想做什么,但我正在努力寻找最好的方法。

我有一个查询返回一些数据:

SELECT
[Description] As [Name], month([OccuredOn]) as [Month], year([OccuredOn]) AS [Year],        COUNT([id]) AS Cnt 
FROM MyTable 
GROUP BY [Description], Year([OccuredOn]), Month([OccuredOn]) 
ORDER BY  [Description],Year([OccuredOn]), month([OccuredOn])

问题是我需要将一些结果合并为一个。

以下是我想要做的,但我需要能够将 string1 和 string2 的记录合并到 string3 的单个记录中。

SELECT
CASE [Description] 
    WHEN 'String1' THEN 'String3' 
    WHEN 'String2' THEN 'String3' 
    ELSE  [Description] 
END As [Name], 
month([OccuredOn]) as [Month], year([OccuredOn]) AS [Year],  COUNT([id]) AS Cnt 
FROM MyTable 
GROUP BY [Description], Year([OccuredOn]), Month([OccuredOn]) 
ORDER BY  [Description],Year([OccuredOn]), month([OccuredOn])

我知道上述方法不是这样做的,但希望有人能指出我可以返回结果的方法,其中任何带有 string1 或 string2 的描述作为该日期的单个唯一行返回,并累积计数。

上面的SQL显然返回了string1和string2的两批数据

谢谢

【问题讨论】:

  • 您是否尝试过 group by [Name] 而不是 group by [Description]
  • 我认为你应该检查 SELECT DISTINCT 而不是 GROUP BY

标签: sql sql-server-2008 merge case


【解决方案1】:

您必须将您的 case 传播到 group byorder by 子句

SELECT
CASE [Description] 
    WHEN 'String1' THEN 'String3' 
    WHEN 'String2' THEN 'String3' 
    ELSE  [Description] 
END As [Name], 
month([OccuredOn]) as [Month], year([OccuredOn]) AS [Year],  COUNT([id]) AS Cnt 
FROM MyTable 
GROUP BY CASE [Description] 
    WHEN 'String1' THEN 'String3' 
    WHEN 'String2' THEN 'String3' 
    ELSE  [Description] 
END, Year([OccuredOn]), Month([OccuredOn]) 
ORDER BY  CASE [Description] 
    WHEN 'String1' THEN 'String3' 
    WHEN 'String2' THEN 'String3' 
    ELSE  [Description] 
END,Year([OccuredOn]), month([OccuredOn])

【讨论】:

  • 完美!这正是我所追求的。非常感谢。
  • 我真的希望他的桌子不要那么大。分组和订单中的案例陈述非常不高效
  • @PlantTheIdea:嗯,有更好的方法吗?
  • @geomagas 自从我从事 SQL Server 工作以来已经有一段时间了,但在 ANSI、Teradata、DB2 和 Oracle 中,您可以按通过 CASE 派生的字段的名称进行分组。这允许优化器使用已经处理过的字段,而不是重新派生两次。这就是为什么我在 cmets 中问“你试过按[Name] 分组吗?”
  • @PlantTheIdea:MS SQL 并非如此。它不接受 group byorder by 中的字段别名。不幸的是,我知道……但事实就是这样。
【解决方案2】:

你能做到吗?

SELECT *
FROM (SELECT
      CASE [Description] 
      WHEN 'String1' THEN 'String3' 
      ELSE  [Description] 
      END As [Name], 
      month([OccuredOn]) as [Month], year([OccuredOn]) AS [Year],  COUNT([id]) AS Cnt 
      FROM MyTable 
      UNION
      SELECT
      CASE [Description] 
      WHEN 'String2' THEN 'String3' 
      ELSE  [Description] 
      END As [Name], 
      month([OccuredOn]) as [Month], year([OccuredOn]) AS [Year],  COUNT([id]) AS Cnt 
      FROM MyTable) 
GROUP BY [Description], Year([OccuredOn]), Month([OccuredOn]) 
ORDER BY  [Description],Year([OccuredOn]), month([OccuredOn])

【讨论】:

  • 如果你走这个方向,推荐使用UNION ALL而不是UNION。您的分组处理唯一性,无需通过UNION 进行验证。
猜你喜欢
  • 1970-01-01
  • 2012-04-23
  • 2012-06-14
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多