mysql查询过滤出基于两种逻辑的数据

xggvc2p6  于 2021-06-19  发布在  Mysql
关注(0)|答案(4)|浏览(435)

这是一个示例表:

sample_id  |      timestamp       | p_id
============================================
    62054    |  2018-09-25 10:18:15 |  2652
    62054    |  2018-09-27 16:44:57 |  966
    62046    |  null                |  1809
    62046    |  2018-09-25 10:18:15 |  2097

我们需要筛选出唯一的sample\u id列,但逻辑是
如果timestamp列为null,则返回那些null列数据

62046 | null | 1809

如果timestamp列不为空,则返回最新的timestamp列数据

62054 | 2018-09-27 16:44:57 | 966

如果有人提供sql查询,那就太好了。
我们需要这样的东西,

WHERE
IF(
    NOT NULL = all row group by sample_id,
    row where cancelled_at is maximum,
    null column
)
ne5o7dgx

ne5o7dgx1#

在上分组 sample_id .
使用if()函数,检查组的时间戳的最小值是否为 null 不管怎样。如果是的话 null ,返回 null ,否则返回max()值。
尝试以下查询:

SELECT sample_id, 
       IF(MIN(timestamp) IS NULL, 
          NULL, 
          MAX(timestamp)) AS timestamp 
FROM your_table 
GROUP BY sample_id
mf98qq94

mf98qq942#

此查询应提供所需的结果。它寻找一排有 NULL 时间戳,或具有 non-NULL timestamp是该sample\u id的最大时间戳,但仅当该sample\u id没有具有 NULL 时间戳:

SELECT *
FROM table1 t1
WHERE timestamp IS NULL OR
      timestamp = (SELECT MAX(timestamp) 
                   FROM table1 t2 
                   WHERE t2.sample_id = t1.sample_id) AND
                   NOT EXISTS (SELECT * 
                               FROM table1 t3
                               WHERE t3.sample_id = t1.sample_id AND
                                     t3.timestamp IS NULL)

输出:

sample_id   timestamp               p_id
62054       2018-09-27T16:44:57Z    966
62046       (null)                  1809
4xrmg8kj

4xrmg8kj3#

找出那些时间不为null的记录,过滤掉timestamp nulls sample\u id,对于null timestamp使用union

select * from t1 where (t1.sample_id,t1.timestamp)
in (

SELECT t.sample_id,max(t.timestamp) AS time
   FROM t1 t
   WHERE t.sample_id NOT IN (select sample_id from t1 where t1.timestamp is null)
     GROUP BY t.sample_id
 )
 UNION
SELECT *
   FROM t1 t 
 WHERE t.timestamp IS NULL

output
    sample_id   timestamp           p_id
    62054       2018-09-27 16:44:57 966
    62046       null                1809
klr1opcd

klr1opcd4#

使用变量:

SELECT sample_id, timestamp, p_id
FROM (
   SELECT sample_id, timestamp, p_id,
          @seq := IF(@s_id = sample_id, @seq + 1,
                     IF(@s_id := sample_id, 1, 1)) AS seq
   FROM mytable
   CROSS JOIN (SELECT @s_id := 0, @seq := 0) AS vars
   ORDER BY 
      sample_id,
      CASE 
         WHEN timestamp IS NULL THEN 1
         ELSE 2
      END,
      timestamp DESC
) AS t
WHERE t.seq = 1;

演示
说明:
要了解其工作原理,您需要执行子查询并检查它产生的输出:

SELECT sample_id, timestamp, p_id,
       @seq := IF(@s_id = sample_id, @seq + 1,
                  IF(@s_id := sample_id, 1, 1)) AS seq
FROM mytable
CROSS JOIN (SELECT @s_id := 0, @seq := 0) AS vars
ORDER BY 
   sample_id,
   CASE 
      WHEN timestamp IS NULL THEN 1
      ELSE 2
   END,
   timestamp DESC

输出:

sample_id   timestamp           p_id    seq
-------------------------------------------
62046       NULL                1809    1
62046       25.09.2018 10:18:15 2097    2
62054       27.09.2018 16:44:57 966     1
62054       25.09.2018 10:18:15 2652    2

你可以在这里看到计算出来的场 seq 用于对每个 sample_id 切片。
注意:如果您使用的是mysql 8.0,那么可以使用窗口函数来实现相同的逻辑。

相关问题