【问题标题】:Select only 1 group from multiple从多个组中仅选择 1 个组
【发布时间】:2018-08-27 13:10:32
【问题描述】:

我有桌子

Id | Provider | Value | IsNew

我想从此表中选择唯一的ProviderValue

SELECT Provider, Value
FROM Table
GROUP BY Provider, Value

但我还需要按 IsNew 字段分组,因为当 Provider = '3' 时我只需要选择“新”记录。

应该是这样的:

Id | Provider | Value | IsNew
______________________________
1  | 1        | 310   | 0
______________________________
2  | 2        | 25    | 0
______________________________
3  | 3        | 250   | 0
______________________________
4  | 3        | 252   | 1

结果我需要选择

Provider | Value 
_________________
1        | 310   
_________________
2        | 25    
_________________
3        | 252  

在实际示例中查询要复杂得多,希望我能解释一下我想要什么。

【问题讨论】:

    标签: sql sql-server select group-by


    【解决方案1】:

    您似乎想要isNew = 1(如果它存在),否则想要其他记录。

    我认为这是你想要的:

    SELECT t.Provider, t.Value
    FROM Table t
    WHERE t.isNew = 1
    UNION ALL
    SELECT t.Provider, t.Value
    FROM Table t
    WHERE t.isNew = 0 AND
          (NOT EXISTS (SELECT 1 FROM table t2 WHERE t2.Provide = t.Provide AND t2.isNew = 1);
    

    Here 是 SQL 小提琴。

    【讨论】:

    • 我不知道这是否允许评论,正确地不允许。但该死的你的斋戒! :) 我几乎花了 2 分钟来阅读问题并提出解决方案。干得好
    • sqlfiddle.com/#!18/2e416/2 我不完全想要的东西......而且我不明白问题出在哪里
    【解决方案2】:

    用 row_number 试试这个:

        select provider, value from 
    (SELECT Provider,value row_number over (partition by provider order by isnew desc) as rn
        FROM Table) a where rn=1 
    

    【讨论】:

    • 值也可以小于“旧”值,所以这不是解决方案
    • 修改查询..你可以试试row_number
    【解决方案3】:

    也许我不太理解,但对我来说这似乎是一个很短的问题:

    select provider, value
      from my_table
      where not (provider = '3' and isnew = 0)
      group by provider, value
    

    这是你需要的吗?

    【讨论】:

    • 当 provider = 3 只有一条 IsNew = 0 的记录时,此查询将不计算记录
    【解决方案4】:

    试试这个:

    select provider,
           [value], 
           isnew
    from (
        select provider,
               [value], 
               isnew,
               row_number() over (partition by Provider order by isnew desc) rn
        from test
    ) a where rn = 1
    

    它将为每个provider 只选择一行,如果有一行,它也会选择新的,这要归功于row_numberorder by isnew desc 子句。

    Demo

    【讨论】:

      【解决方案5】:

      您可以像用户 fa06 建议的那样使用 ROW_NUMBER() 函数。在下面的例子中使用公用表表达式来达到预期的结果

      ;WITH CTE AS
      (
        SELECT Provider, Value, ROW_NUMBER() OVER (PARTITION BY Provider ORDER BY IsNew DESC) 
        AS Row_Rank FROM Test 
      )
      SELECT * FROM CTE WHERE Row_Rank = 1
      

      以下是工作示例: http://sqlfiddle.com/#!18/2e416/19

      如果有帮助请告诉我

      【讨论】:

        【解决方案6】:

        这是我的两分钱:

        SELECT a.Provider, a.Value, a.IsNew
        FROM Table a LEFT JOIN Table b ON a.Provider = b.Provider AND a.IsNew <> b.IsNew
        WHERE a.IsNew = 1 OR b.IsNew IS NULL
        

        输出是:

        Provider Value IsNew
        -------- ----- -----
        1          310     0
        2           25     0
        3          252     1
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-12-25
          • 2018-12-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多