0

我有一个返回结果如下的 Sql 表:

Amount  Descrip
----------------------------
1.34    Group1  Description1
2.36    Group2  Description2
5.46    Group3  Description3
4.54    Group1  Description4
6.23    Group2  Description5

我需要让它看起来像这样。

Descrip      Group1 Group2  Group3 
------------------------------------
Description1 1.34
Description2        2.36 
Description3                5.46
Description4 4.54
Description5        6.23

要记住的是,没有固定规则表明第 3 组或任何组将存在。组列表由查询结果确定。我可以一次拥有 Group1、Group2、Group4 和 Group6,而没有 group4,但又拥有 group5。

我知道我可以在 .Net 代码中做到这一点,但在代码中会很耗时。我宁愿在 SQL 服务器中执行它,只绑定到结果集。

作为旁注,如果有一种方法可以汇总这些值以获得底部的总计(例如 Group1 的 5.88),那就太好了。我可以在运行时进行计算,但如果可以的话,我也想在服务器端进行计算。

4

3 回答 3

0

看看使用枢轴

SELECT 'Amount' AS MaxAmount, [Group1], [Group2], [Group3]
  FROM
(SELECT descrip, Amount 
    FROM Table) AS SourceTable
PIVOT
(
Max(Amount)
FOR descrip IN ([Group1], [Group2], [Group3])
) AS PivotTable;

需要放入适当的聚合函数,在这个例子中我使用了 max。

于 2009-10-12T15:28:43.303 回答
0

就像 SeriousCallersOnly 所说的那样,您需要一个枢轴语句。不幸的是,要使用这些,您必须在要旋转的实际值(“Group1”、“Group2”、“Group3”等)中进行硬编码。如果直到运行时才能确定它们,则必须在运行时构建查询,这意味着构建和执行动态代码。这并不简单。如果您确实必须经常进行此类查询,那么您将 [必须] 相当擅长它;如果这是您认为您会做的唯一地方,那么您最好将应用程序方面的工作背负起来。

(另一种可能性:在所有可能的透视值中进行硬编码,然后让应用程序忽略“空”列。如果透视值是随机的、任意的或用户输入的,这将不起作用。)

于 2009-10-12T15:43:22.680 回答
0

当您想将行数据更改为列(AKA pivot)时,最广泛支持的方法是使用 CASE 语句:

SELECT t.descrip,
       CASE WHEN t.descrip LIKE 'GROUP 1%' THEN t.amount END 'Group 1',
       CASE WHEN t.descrip LIKE 'GROUP 2%' THEN t.amount END 'Group 2',
       CASE WHEN t.descrip LIKE 'GROUP 3%' THEN t.amount END 'Group 3',
       ...etc

然而,这也意味着如果您没有特定描述的记录,则该值将显示为NULL。SQL 是全有或全无的事情 - 列将出现或不在整个结果集中。

根据您的数据库,有一些语法可以提供帮助。例如,SQL Server 从 SQL Server 2005 开始就支持 PIVOT 功能。Oracle 在 11g 中添加了它。我不相信 MySQL 或 Postgres 具有枢轴功能 - 你必须使用 CASE 语句。

至于拥有动态组,您需要使用动态 SQL 来适应。CASE 和 PIVOT 功能都无法处理此问题 - 必须为查询定义输出列。

于 2009-10-12T16:04:43.400 回答