【问题标题】:SQL query for GROUP BY, with COALESCE, LEAST, MINGROUP BY 的 SQL 查询,包含 COALESCE、LEAST、MIN
【发布时间】:2023-03-06 10:01:01
【问题描述】:

我想编写一个 SQL 查询来调用具有一些复杂条件的多个列。我正在使用 RMySQL 包在 R Studio 上工作。我的服务器是 MySQL。

表格是这样的。

organisation    Tour_ID             A           B           C           D  
Ikea                  a    2018-04-01  2018-05-07  2018-05-09  2018-05-01
Ikea                  a    2018-06-01  2018-05-03  2018-05-29          NA   
Ikea                  a    2018-04-02  2018-05-01  2018-07-08  2018-05-26 
Ikea                  b    2018-06-02  2018-05-01          NA  2018-05-26
Ikea                  b    2018-06-02  2018-05-01          NA  2018-05-26
Ikea                  b            NA  2018-05-05  2018-08-02  2018-06-01
Ikea                  c    2018-06-01  2018-05-07  2018-05-09  2018-05-01
Ikea                  c    2018-06-01  2018-05-03          NA          NA   
Ikea                  c    2018-08-02  2018-05-09  2018-07-08  2018-05-26

这就是我想做的:

  1. 过滤organisation = Ikea所在的行
  2. groupby by Tour_ID 像这样:

    organisation    Tour_ID             A           B           C           D  
    Ikea                  a    2018-04-01  2018-05-07  2018-05-09  2018-05-01
    Ikea                  a    2018-06-01  2018-05-03  2018-05-29          NA   
    Ikea                  a    2018-04-02  2018-05-01  2018-07-08  2018-05-26 
    
    
    Ikea                  b    2018-06-02  2018-05-01          NA  2018-05-26
    Ikea                  b    2018-06-02  2018-05-01          NA  2018-05-26
    Ikea                  b            NA  2018-05-05  2018-08-02  2018-06-01
    
    
    Ikea                  c    2018-06-01  2018-05-07  2018-05-09  2018-05-01
    Ikea                  c    2018-06-01  2018-05-03          NA          NA   
    Ikea                  c    2018-08-02  2018-05-09  2018-07-08  2018-05-26
    
  3. 在每组Tour_ID 中,查看ABCD 列中的最早日期。如果组中四列中最早的日期在2018-05-012018-05-31 之间,则返回整个组。如果一行包含 NA 值,我想忽略 NAs 并查看其余值中最早的日期。比如Tour_ID = a这组,最早的日期是2018-04-01,所以不符合条件。

总之,只有Tour_ID = bTour_ID = c 的组符合条件。结果应该是:

organisation    Tour_ID             A           B           C           D
Ikea                  b    2018-06-02  2018-05-01          NA  2018-05-26
Ikea                  b    2018-06-02  2018-05-01          NA  2018-05-26
Ikea                  b            NA  2018-05-05  2018-08-02  2018-06-01
Ikea                  c    2018-06-01  2018-05-07  2018-05-09  2018-05-01
Ikea                  c    2018-06-01  2018-05-03          NA          NA   
Ikea                  c    2018-08-02  2018-05-09  2018-07-08  2018-05-26

我应该如何编写 SQL 查询? 这是我的尝试:

"SELECT t.* FROM myTable JOIN (SELECT organisation, Tour_ID 
                                                   FROM myTable
                                                   WHERE organisation LIKE 'Ikea' AND
                                                   GROUP BY organisation, Tour_ID
                                                   HAVING LEAST(COALESCE(MIN(A), '2119-01-01'), 
                                                                COALESCE(MIN(B), '2119-01-01'), 
                                                                COALESCE(MIN(C), '2119-01-01'), 
                                                                COALESCE(MIN(D), '2119-01-01')) >= '2018-05-01' AND
                                                          LEAST(COALESCE(MIN(A), '2119-01-01'), 
                                                                COALESCE(MIN(B), '2119-01-01'), 
                                                                COALESCE(MIN(C), '2119-01-01'), 
                                                                COALESCE(MIN(D), '2119-01-01')) < '2018-06-01'
                                                  ) tt
                                                  ON tt.Tour_ID = t.Tour_ID AND
                                                     tt.organisation = t.organisation"

但我不认为它正确选择了Tour_ID = c,因为使用了COALESCE

对于Tour_ID = c的组,D列中有NA,所以COALESCE(MIN(D), '2119-01-01')返回2119-01-01。但它不应该,因为D 列中的最小值是2018-05-01,这必须与ABC 列中的最小值进行比较。事实上,D 列中的2018-05-01 是整个组中的最小值,所以我认为COALESCE(MIN(D), '2119-01-01') 是错误的。

但我不知道有什么解决方案。任何帮助将不胜感激!

【问题讨论】:

  • 是否只有 a、b、c、d 列?
  • 有80列但这里我只关心这四个

标签: mysql sql group-by min coalesce


【解决方案1】:

P.Salmon 的解决方案假定当整个组织中的最低日期 + Tour_ID 在给定时间范围内时,则需要显示该日期。 当您想在时间范围内 A、B、C 或 D 中的任何 1 行具有最低值时显示组,您需要这样:

SELECT myTable.*
FROM myTable 
JOIN (
   SELECT organisation, tour_id
   FROM myTable
   WHERE  
         LEAST(COALESCE(A, '2119-01-01'), COALESCE(B, '2119-01-01'), 
               COALESCE(C, '2119-01-01'), COALESCE(D, '2119-01-01'))
         BETWEEN '2018-05-01' AND '2018-05-31'
   GROUP BY organisation,tour_id
) s ON s.organisation = myTable.organisation AND s.tour_id = myTable.tour_id
WHERE myTable.organisation = 'ikea';

【讨论】:

  • 更清晰、更准确的 IMO 答案,但应保留为 JOIN,以仅获取结果集中预期的人的日期。
  • 非常感谢您的回答。对不起,我是 SQL 的初学者,但是我应该在哪里声明表的名称 myTable?另外,我认为存在语法错误(可能在AND '2018-05-31' 之后缺少)?但我不确定...
  • from 和 where 子句是错误的。
  • 这根本不起作用,即使你从和 where 子句翻转
  • 更改了查询以将“myTable”添加到其中并修复了 FROM 和 WHERE 错误。
【解决方案2】:

我会使用 and if 而不是合并并稍微重新排列代码

select t.*
from t 
join
(
select organisation,tour_id,
        min(
        least(if(a='na',date(now()),a),if(b='na',date(now()),b),if(c='na',date(now()),c),if(d='na',date(now()),d))
        ) mindt
from t
group by organisation,tour_id
) s on s.organisation = t.organisation and s.tour_id = t.tour_id
where t.organisation = 'ikea' and s.mindt between '2018-05-01' and '2018-05-31';

+----+--------------+---------+------------+------------+------------+------------+
| id | organisation | Tour_ID | A          | B          | C          | D          |
+----+--------------+---------+------------+------------+------------+------------+
|  4 | Ikea         | b       | 2018-06-02 | 2018-05-01 | NA         | 2018-05-26 |
|  5 | Ikea         | b       | 2018-06-02 | 2018-05-01 | NA         | 2018-05-26 |
|  6 | Ikea         | b       | NA         | 2018-05-05 | 2018-08-02 | 2018-06-01 |
|  7 | Ikea         | c       | 2018-06-01 | 2018-05-07 | 2018-05-09 | 2018-05-01 |
|  8 | Ikea         | c       | 2018-06-01 | 2018-05-03 | NA         | NA         |
|  9 | Ikea         | c       | 2018-08-02 | 2018-05-09 | 2018-07-08 | 2018-05-26 |
+----+--------------+---------+------------+------------+------------+------------+
6 rows in set (0.00 sec)

【讨论】:

  • 感谢您的回答。在这种情况下我应该在哪里声明表的名称myTable
  • 我将t 替换为myTable 但返回了0 行...你知道为什么吗?
  • 我应该把myTable放在哪里?
  • 有人能解释为什么这个答案不包含myTable吗?不提表名怎么查询?
  • 我已选择调用表 t
猜你喜欢
  • 1970-01-01
  • 2018-10-26
  • 2013-04-06
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 1970-01-01
  • 2012-07-25
  • 1970-01-01
相关资源
最近更新 更多