【问题标题】:SQL. Checking condition and marking in a columnSQL。检查条件并在列中标记
【发布时间】:2019-06-16 21:48:18
【问题描述】:

这是我的 PEOPLE 表,我在其中存储姓名、姓氏、DOB(出生日期)和其他一些数据。在一个新查询中,我需要为具有相同姓名和姓氏组合的人添加额外的列。这是条件:

  • 遍历每组具有相同姓名和姓氏组合的人,在附加字段中标记那些 DOB 不是最大值和最小值的人(仅与相同的姓名和姓氏相比)
  • 如果只有 1 或 2 次出现相同的姓名和姓氏,请无论如何标记它们

这是查询的结果

解释:

  • John Doe 标记为仅见过一次
  • Tom Taylor 标记为只见过两次
  • 除了具有最小和最大 DOB 的记录外,Alice Smith 和 Bob Brown 在任何地方都做了标记

请帮助形成所需输出的 ​​SQL 查询。这是我的理解(猜测)

  • 获取唯一姓名和姓氏对的列表,(出现次数 >2 ??? )
  • 为每个唯一对找到具有最小和最大 DOB 的行(避免它们)
  • 在新的 CheckBox 列中标记剩下的那些(不是极值)

【问题讨论】:

  • 我能想到的另一种方法是:选择具有 MIN 和 MAX DOB 的行,其中唯一 Name&Surname > 2 的出现,避免它们,标记其他所有内容

标签: mysql sql select subquery


【解决方案1】:

首先group by name, surname 获取每个姓名和姓氏的出现次数以及最小和最大 dob 并将结果连接到表中。
使用 CASE 语句应用条件:

select 
  p.*,
  case  
    when g.counter in (1, 2) then 'mark'
    else case
      when p.dob not in (g.mindob, g.maxdob) then 'mark' 
    end
  end Checkbox
from peaople inner join (
  select 
    name, surname,
    count(*) counter,
    min(dob) mindob,
    max(dob) maxdob
  from people
  group by name, surname
) g on g.name = p.name and g.surname = p.surname

【讨论】:

    【解决方案2】:

    在 MySQL 8+ 中使用窗口函数:

    select p.*,
           (case when count(*) over (partition by name, surname) <= 2
                 then 'mark'
                 when row_number() over (partition by name, surname order by dob) > 1 and
                      row_number() over (partition by name, surname order by dob desc) > 1
                 then 'mark'
            end) as checkbox
    from people p;
    

    注意:如果最早或最晚出生日期有重复,则仅排除其中一个。如果要排除所有这些,请使用rank() 而不是row_number()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-04
      • 2014-08-20
      • 2018-07-27
      • 1970-01-01
      • 2023-02-25
      • 2015-12-26
      相关资源
      最近更新 更多