【问题标题】:SELECT non duplicated rows with priority value选择具有优先级值的非重复行
【发布时间】:2020-05-04 10:40:54
【问题描述】:

我有一个表,其中包含带有测量值的行。对于同一个批次 id,可以指定多个度量。我想在以下条件下得到正确的值:

  • 如果给定批次只有一行,则度量有效
  • 如果有多行相同类型,则度量无效,返回的类型应为“无效”,值 = 0
  • 如果有不止一行不同类型(一个“已获得”和一个“已验证”),则返回的行必须是“已验证”行

样本数据:

create table measures (
  batch  int,
  type   varchar(24),
  value int
);

insert into measures select 01,'Verified',10;
insert into measures select 02,'Acquired',34;
insert into measures select 03,'Verified',22;
insert into measures select 03,'Verified',24;
insert into measures select 04,'Verified',32;
insert into measures select 04,'Acquired',34;
insert into measures select 05,'Acquired',42;
insert into measures select 05,'Acquired',44;

样本输出:

01   Verified   10
02   Acquired   34
03   Invalid    0
04   Verified   32
05   Invalid    0

【问题讨论】:

  • 你的第一个条件似乎与其他两个条件有关。
  • 这是一种非常奇怪的方式来编写 INSERT 语句。 VALUES 子句有什么问题?
  • 您使用的是哪个DBMS 产品? “SQL”只是一种查询语言,而不是特定数据库产品的名称。请为您正在使用的数据库产品添加tagWhy should I tag my DBMS
  • db引擎是SQL SERVER,我已经加了tag。

标签: sql sql-server select duplicates


【解决方案1】:

你的逻辑有点难以理解。你可以用条件聚合做你想做的事。它认为逻辑是:

select batch,
       (case when count(*) = 1 then max(type)
             when min(type) = max(type) then 'Invalid'
             else coalesce(max(case when type = 'Verified' then 'Verified' end), 'Invalid')
        end) as type,
       (case when count(*) = 1 then max(value)
             when min(type) = max(type) then 0
             else coalesce(max(case when type = 'Verified' then value end), 0)
        end) as value
from measures m
group by batch;

【讨论】:

    【解决方案2】:

    使用windows函数:

    ;WITH CountTypesPerBatch AS
    (
        SELECT batch, type, value,
               COUNT(CASE WHEN type = 'Verified' THEN 1 END) 
                  OVER (PARTITION BY batch) AS verified,
               COUNT(CASE WHEN type = 'Acquired' THEN 1 END) 
                  OVER (PARTITION BY batch) AS acquired,
               ROW_NUMBER() OVER (PARTITION BY batch 
                                  ORDER BY IIF(type='Verified',1, 2)) seq
        FROM measures
    )
    SELECT DISTINCT batch, 
           CASE 
              WHEN verified > 1 OR acquired > 1 THEN 'invalid' 
              WHEN verified = 1 THEN 'verified'
              ELSE 'acquired'
           END,
           CASE 
              WHEN verified > 1 OR acquired > 1 THEN 0
              ELSE value
           END
    FROM CountTypesPerBatch
    WHERE seq = 1
    

    Demo here

    【讨论】:

      猜你喜欢
      • 2021-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多