【问题标题】:SQL - get min values from a column based on values from two other columnsSQL - 根据其他两列的值从一列中获取最小值
【发布时间】:2021-09-09 02:43:02
【问题描述】:

我正在尝试为第三列中唯一值的每个实例收集小于在第二列中具有特定值的列的另一个值的列的值。

这是一个例子。

user_name time succeeds
bill 0300 no
bill 0400 yes
bill 0500 no
annie 1200 yes
annie 1400 yes
jonny 0900 no
jonny 1000 no
jonny 1400 yes
jonny 1900 yes

所以对于每个用户,我想找到他们成功的最早时间(“是”),然后收集这些时间以下的所有时间。

对于账单,这将是 0300 安妮没有时间 对于 jonny,这将是 1000 和 0900

【问题讨论】:

  • 你使用的是哪个数据库?
  • 还有预期的输出表是什么样的?
  • @drum。 SQLite lang 和 table 将是名称和时间(时间是成功之前的时间)。
  • 不确定 SQLite 是否支持该语法,但一种方法是 CROSS APPLY 为特定用户名找到“是”的最短时间,然后在原始查询中使用它来隔离“没有”在那之前的记录

标签: sql sqlite


【解决方案1】:
select t1.*,t2.sumTimeUnSucceeds,t2.concatenateTimeUnSucceeds from
(select user_name,min(time1) as minTimeSucceeds from Mytable 
 where succeeds = "yes" group by user_name) as t1
left join 
(select user_name,sum(time1) as sumTimeUnSucceeds, 
 group_concat(time1) as concatenateTimeUnSucceeds from Mytable 
 where succeeds = "no" group by user_name) as t2
on t1.user_name = t2.user_name;

SQL Fiddle

【讨论】:

    【解决方案2】:

    WHERE 子句中使用相关子查询,该子查询为每个user_name 返回带有succeeds = 'yes' 的第一行:

    SELECT t1.*
    FROM tablename t1
    WHERE t1.time < (
      SELECT MIN(CASE WHEN t2.succeeds = 'yes' THEN t2.time END)
      FROM tablename t2
      WHERE t2.user_name = t1.user_name
    );
    

    或者:

    SELECT t1.*
    FROM tablename t1
    WHERE t1.time < (
      SELECT t2.time
      FROM tablename t2
      WHERE t2.user_name = t1.user_name AND t2.succeeds = 'yes'
      ORDER BY t2.time LIMIT 1
    );
    

    或者,NOT EXISTS:

    SELECT t1.*
    FROM tablename t1
    WHERE NOT EXISTS (
      SELECT 1
      FROM tablename t2
      WHERE t2.user_name = t1.user_name 
        AND t2.succeeds = 'yes'
        AND t2.time <= t1.time
    );
    

    请参阅demo

    【讨论】:

    • 相关子查询是可能的,但通常比非相关子查询表现更差。除了一次性查询之外,我会避免在任何情况下这样做(即使那样,它也比干净的 CTE 更复杂)
    • @Megadest 相关子查询用于与非相关子查询不同的情况。这就是为什么有“非”前缀的原因。如果您有不相关子查询的解决方案,为什么不发布它?
    • “在不同情况下使用”完全正确。但不是在这个。已经有这个问题的答案不使用相关子查询。如果您想要另一个供自己使用,请点击此处:sqlfiddle.com/#!5/6bb46/14/0 比较计划并在拥有数百条记录后立即享受性能提升 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 2016-11-30
    • 1970-01-01
    相关资源
    最近更新 更多