SQL select aggregate group by:根据条件

时间:2015-09-10 22:07:12

标签: sql sql-server-2008

我有一张如下表格:

trans_id  index_no    meals     tips   coverage  SID
021253    DET98313    30.50     2.54   CORP      ZX984784
031823    DET98313    20.45     0.89   SELF      ZX984784
017265    DET98313    22.48     2.89   CORP      ZX984784
051346    DET98313    18.63     2.02   SELF      ZX984784
 EX023    DET98313    23.45     1.45   CORP      LN874742
...

所显示的行形成由index_no标识的组和由coverage标识的子组。

我想要做的是计算组中mealstips的总和,并得到SID ZX984784

我可以做的是排除UN874742,我知道trans_ID将以两个字母开头,而不仅仅是其他行的数字。

现在我提出了以下问题:

SELECT index_no, 
    coverage,
    SUM(meals) as meals,
    SUM(tips) as tips,
    MIN(SID) as SID
FROM
    myTable
GROUP BY
    index_no, coverage

但MIN(SID)无法保证给我SID ZX984784

我想要的输出是:

index_no    coverage  meals     tips      SID
DET98313        CORP  76.43     6.88   ZX984784
DET98313        SELF  39.08     2.91   ZX984784

` 如何在SUM操作中包含最后一行,但同时在检索SID时将其排除?

2 个答案:

答案 0 :(得分:1)

以下想法应该适用于大多数数据库:

select . . .,
       min(case when substring(trans_id, 1, 2) between 'AA' and 'ZZ' 
                 then NULL else SID
           end)

这可能已经足够了:

substring()

注意:某些数据库会调用substr()select . . ., min(case when trans_id like '[A-Z][A-Z]%' then NULL else SID end)

大多数数据库都有一些更容易的特殊用途机制。例如,在SQL Server中:

s2

答案 1 :(得分:0)

您可能可以制作条件MIN

这使用SQL SERVER中的isnumeric

SQL FIDDLE DEMO

SELECT index_no, 
    coverage,
    SUM(meals) as meals,
    SUM(tips) as tips,
    MIN( CASE 
           WHEN ISNUMERIC(trans_id  + '.0e0') = 1 THEN SID
           ELSE NULL
         END ) as SID
FROM
    myTable
GROUP BY
    index_no, coverage

Select only string with number SQL Server