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

时间:2018-09-30 06:05:43

标签: mysql sql

这是一个示例表:

  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_id列,但逻辑是

  1. 如果时间戳列为空,则返回这些空列数据

        62046 | null | 1809
    
  2. 如果时间戳列不为空,则返回最新的时间戳列数据

     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
)

4 个答案:

答案 0 :(得分:4)

此查询应为您提供所需的结果。它会寻找具有NULL时间戳的行,或具有non-NULL时间戳的行,该时间戳是该sample_id的最大时间戳,但前提是该sample_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

答案 1 :(得分:1)

使用变量:

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;

Demo

说明:

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

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,则可以使用窗口函数来实现相同的逻辑。

答案 2 :(得分:1)

找出时间不为空的那些记录并过滤掉    时间戳记将sample_id设为null,并将时间戳记设为null  使用联合

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

答案 3 :(得分:0)

  • sample_id分组。
  • 使用If()函数,检查组的时间戳记minimum value是否为null。如果它是null,则返回null,否则返回Max()值。

尝试以下查询:

SELECT sample_id, 
       IF(MIN(timestamp) IS NULL, 
          NULL, 
          MAX(timestamp)) AS timestamp 
FROM your_table 
GROUP BY sample_id    
相关问题