【问题标题】:Group more records based on values根据值对更多记录进行分组
【发布时间】:2017-03-13 07:31:36
【问题描述】:

我有下表:

contract_nr id_supplier id_seller id_vendor 01 1521 空空 01 1521 2 空 01 空 空 538 02 空 空 154 02 无 无 159 03 2626 17 空 03 空 17 124

结果应该是一个包含基于这些规则的类别字段的分组表:

  1. 如果有一个 id_supplier 或 id_seller 不是 NULL,那么它是 类别1
  2. 如果只有 id_vendor 和 id_supplier 且 id_seller 为 NULL, 那么就是category2

结果应该是这样的:

contract_nr 类别 01 类别1 02 类别2 03 类别1

【问题讨论】:

  • 你尝试了什么?
  • 阻塞时应该使用大小写
  • 如果全部为空怎么办?

标签: mysql sql


【解决方案1】:

您可以使用与 case 表达式配对的聚合来检查数据所需的条件:

select
    contract_nr,
    case
        when max(id_supplier) is not null 
                or max(id_seller) is not null
            then 'category1'
        when max(id_vendor) is not null
                and max(id_supplier) is null 
                and max(id_seller) is null
            then 'category2'
    end as category
from your_table
group by contract_nr;

它使用了 max 返回聚合组中最大非空值的事实。如果组中只有空值,则它将返回空值。

另外请注意,如果两个条件都不满足,它将在类别中返回null。您可能需要在案例中添加一个else 'category3' 来捕获它。

Demo

【讨论】:

  • 大小写表达,而非陈述。
【解决方案2】:

你可以使用条件聚合

SELECT contract_nr,
       CASE 
          WHEN SUM(id_supplier IS NOT NULL) + SUM(id_seller IS NOT NULL) >= 1 
             THEN 'category1'
          WHEN SUM(id_vendor IS NOT NULL) THEN 'category2'
          ELSE 'N/A'
       END   
FROM mytable
GROUP BY contract_nr;

在 MySQL 中,您可以将SUM 与布尔表达式一起使用,以查找每个组中满足条件的次数。因此,使用谓词:

SUM(id_supplier IS NOT NULL) + SUM(id_seller IS NOT NULL) >= 1

我们可以测试,对于给定的contract_nr,是否存在至少一个记录具有或者id_supplier@987654327 @,或两者都不为空。

Demo here

【讨论】:

  • 根据OP给出的要求,这个答案实际上是错误的。在第二点中,它明确指出如果 id_vendor 不为 null 并且 id_supplier id_seller 为 NULL,则为 category2。如果OP认为这是正确的答案,那么问题就有问题
  • @GurV 如果满足CASE表达式的第二个WHEN子句的谓词,则表示第一个WHEN子句的谓词是not 满意。这意味着在第二个WHEN 子句中重复第一个WHEN 子句的谓词是多余的。
  • 不。首先当有一个 OR 检查,其次需要一个 AND 检查。所以,不是那么多余。
  • @GurV no OR 签入first WHEN。如果SUM(id_supplier IS NOT NULL) + SUM(id_seller IS NOT NULL) 不是> 1,则它等于0,这意味着对于属于同一contract_nr 组的所有记录,两个字段(id_supplierid_seller)都是NULL。跨度>
  • 天哪,我错过了,抱歉。那么显然你的第一个when 是错误的。查看问题
【解决方案3】:

按contract_nr 分组,然后使用case whencount(不包括空值)来执行此操作:

select
    contract_nr,
    case when count(id_supplier) = 0 and count(id_seller) = 0 and count(id_vendor) > 0 then 'category2'
         else 'category1'
    end as category
from yourtable
group by contract_nr

参见 sqlfiddle 中的demo

【讨论】:

    猜你喜欢
    • 2019-02-10
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-28
    • 2017-03-30
    相关资源
    最近更新 更多