SQL 查询 GROUP BY, return 符合 LEAST, COALESCE 条件的分组
SQL query for GROUP BY, return groups that match the conditions of LEAST, COALESCE
我想编写一个 SQL 查询来调用多个条件有点复杂的列。我正在使用 RMySQL 包开发 R Studio。我的服务器是 MySQL.
table 看起来像这样。
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
这就是我想要做的:
- 过滤
organisation = Ikea
所在的行
按 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
在每组 Tour_ID
中,查看 A
、B
、C
和 D
列中的最早日期.如果组中四列中最早的日期在2018-05-01
和2018-05-31
之间,则return整个组。如果一行包含 NA
值,我想忽略 NA
并查看其余值中最早的日期。例如Tour_ID = a
组,最早日期是2018-04-01
,不符合条件
综上所述,只有Tour_ID = b
和Tour_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 查询?
这是我的尝试,但我只是不知道如何进行分组,以及如何 return 整个组而不仅仅是最早日期的行。
SELECT *
FROM myTable
WHERE organisation LIKE 'Ikea' AND
GROUP BY 'Tour_ID' AND
LEAST(COALESCE(A, '2019-01-01'), COALESCE(B, '2019-01-01'), COALESCE(C, '2019-01-01'), COALESCE(D, '2019-01-01')) >= '2018-05-01' AND
LEAST(COALESCE(A, '2019-01-01'), COALESCE(B, '2019-01-01'), COALESCE(C, '2019-01-01'), COALESCE(D, '2019-01-01')) < '2018-06-01';
('2019-01-01' 是替换 NAs)
感谢您的各种帮助!
添加:
根据 Gordon 的回答,我在这里重写了 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"
我 运行 dbGetQuery
来自 RMySQL 包。但是我收到以下错误。我不明白,因为 GROUP BY
部分看起来还不错。有谁知道我为什么会收到此错误消息?
dbGetQuery(connection = connection, statement = condition)
Error in .local(conn, statement, ...) : could not run statement: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY organisation, Tour_ID HAVING LEAST(COALESCE(A' at line 1
先获取符合条件的tour_id
:
SELECT Tour_ID
FROM myTable
WHERE organisation LIKE 'Ikea'
GROUP BY Tour_ID
HAVING LEAST(COALESCE(MIN(A), '2019-01-01'), COALESCE(MIN(B), '2019-01-01'), COALESCE(MIN(C), '2019-01-01'), COALESCE(MIN(D), '2019-01-01')) >= '2018-05-01' AND
LEAST(COALESCE(MIN(A), '2019-01-01'), COALESCE(MIN(B), '2019-01-01'), COALESCE(MIN(C), '2019-01-01'), COALESCE(MIN(D), '2019-01-01')) < '2018-06-01';
然后将其放入查询中以获取原始行。这是一种方法:
select t.*
from mytable t join
(SELECT organisation, Tour_ID
FROM myTable
WHERE organisation LIKE 'Ikea'
GROUP BY organisation, Tour_ID
HAVING LEAST(COALESCE(MIN(A), '2019-01-01'), COALESCE(MIN(B), '2019-01-01'), COALESCE(MIN(C), '2019-01-01'), COALESCE(MIN(D), '2019-01-01')) >= '2018-05-01' AND
LEAST(COALESCE(MIN(A), '2019-01-01'), COALESCE(MIN(B), '2019-01-01'), COALESCE(MIN(C), '2019-01-01'), COALESCE(MIN(D), '2019-01-01')) < '2018-06-01'
) tt
ON tt.tour_id = t.tour_id AND
tt.organisation = t.organisation;
我想编写一个 SQL 查询来调用多个条件有点复杂的列。我正在使用 RMySQL 包开发 R Studio。我的服务器是 MySQL.
table 看起来像这样。
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
这就是我想要做的:
- 过滤
organisation = Ikea
所在的行
按
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
在每组
Tour_ID
中,查看A
、B
、C
和D
列中的最早日期.如果组中四列中最早的日期在2018-05-01
和2018-05-31
之间,则return整个组。如果一行包含NA
值,我想忽略NA
并查看其余值中最早的日期。例如Tour_ID = a
组,最早日期是2018-04-01
,不符合条件
综上所述,只有Tour_ID = b
和Tour_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 查询? 这是我的尝试,但我只是不知道如何进行分组,以及如何 return 整个组而不仅仅是最早日期的行。
SELECT *
FROM myTable
WHERE organisation LIKE 'Ikea' AND
GROUP BY 'Tour_ID' AND
LEAST(COALESCE(A, '2019-01-01'), COALESCE(B, '2019-01-01'), COALESCE(C, '2019-01-01'), COALESCE(D, '2019-01-01')) >= '2018-05-01' AND
LEAST(COALESCE(A, '2019-01-01'), COALESCE(B, '2019-01-01'), COALESCE(C, '2019-01-01'), COALESCE(D, '2019-01-01')) < '2018-06-01';
('2019-01-01' 是替换 NAs)
感谢您的各种帮助!
添加: 根据 Gordon 的回答,我在这里重写了 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"
我 运行 dbGetQuery
来自 RMySQL 包。但是我收到以下错误。我不明白,因为 GROUP BY
部分看起来还不错。有谁知道我为什么会收到此错误消息?
dbGetQuery(connection = connection, statement = condition)
Error in .local(conn, statement, ...) : could not run statement: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY organisation, Tour_ID HAVING LEAST(COALESCE(A' at line 1
先获取符合条件的tour_id
:
SELECT Tour_ID
FROM myTable
WHERE organisation LIKE 'Ikea'
GROUP BY Tour_ID
HAVING LEAST(COALESCE(MIN(A), '2019-01-01'), COALESCE(MIN(B), '2019-01-01'), COALESCE(MIN(C), '2019-01-01'), COALESCE(MIN(D), '2019-01-01')) >= '2018-05-01' AND
LEAST(COALESCE(MIN(A), '2019-01-01'), COALESCE(MIN(B), '2019-01-01'), COALESCE(MIN(C), '2019-01-01'), COALESCE(MIN(D), '2019-01-01')) < '2018-06-01';
然后将其放入查询中以获取原始行。这是一种方法:
select t.*
from mytable t join
(SELECT organisation, Tour_ID
FROM myTable
WHERE organisation LIKE 'Ikea'
GROUP BY organisation, Tour_ID
HAVING LEAST(COALESCE(MIN(A), '2019-01-01'), COALESCE(MIN(B), '2019-01-01'), COALESCE(MIN(C), '2019-01-01'), COALESCE(MIN(D), '2019-01-01')) >= '2018-05-01' AND
LEAST(COALESCE(MIN(A), '2019-01-01'), COALESCE(MIN(B), '2019-01-01'), COALESCE(MIN(C), '2019-01-01'), COALESCE(MIN(D), '2019-01-01')) < '2018-06-01'
) tt
ON tt.tour_id = t.tour_id AND
tt.organisation = t.organisation;