SQL 查询调用带条件的多列(带 NAs)
SQL query for calling multiple columns with conditions(with NAs)
这是我 的一个连续问题。我想编写一个 SQL 查询,调用多个带条件的列。我正在使用 RMySQL 包开发 R Studio。我的服务器是 MySQL.
table 看起来像这样。
organisation A B C D
Ikea 2018-04-01 2018-05-07 2018-05-09 2018-05-01
Ikea 2018-06-01 2018-05-03 2018-05-29 NA
Orange 2018-04-02 2018-05-01 2018-07-08 2018-05-26
Ikea 2018-06-02 2018-05-01 NA 2018-05-26
Nestle 2018-06-02 2018-05-01 NA 2018-05-26
Ikea NA 2018-05-05 2018-04-02 2018-06-01
我想得到一行,其中组织是宜家,四列(A、B、C、D)中最早的日期在 2018-05-01 和 2018-05-31 之间。
在包含 NA 值的行中,我想忽略 NA 并查看其余值中最早的日期。例如,对于第二行,最早的日期是“2018-05-03”(B列),因此它符合条件。
所以只有原来table上面的第二第四行符合条件。而我想要得到的结果应该是:
organisation A B C D
Ikea 2018-06-01 2018-05-03 2018-05-29 NA
Ikea 2018-06-02 2018-05-01 NA 2018-05-26
我应该如何编写 SQL 查询?
这是我从上一个问题得到答案后的尝试,但它不适用于带有 NA 的行。
SELECT * FROM myTable
WHERE organisation LIKE Ikea
LEAST(A, B, C, D) >= '2018-05-01' AND
LEAST(A, B, C, D) < '2018-06-01'
感谢您的各种帮助!
您可以尝试使用 IFNULL()
作为值并使用 getdate()
所以如果它为 null 它只会在今天使用然后那不会被认为是最少的,这基本上是忽略它们。
赞:LEAST(IFNULL(A,getdate()), IFNULL(B,getdate()), IFNULL(C,getdate()), IFNULL(D,getdate()))
希望这可以将您推向正确的方向
除非 NA
是其中的一个字符串,您可以使用 case when A = 'NA' THEN getdate() end
这样的 case 语句
最终可能看起来像
SELECT * FROM myTable
WHERE organisation LIKE Ikea
LEAST(IFNULL(A,getdate()), IFNULL(B,getdate()), IFNULL(C,getdate()), IFNULL(D,getdate())) >= '2018-05-01' AND
LEAST(IFNULL(A,getdate()), IFNULL(B,getdate()), IFNULL(C,getdate()), IFNULL(D,getdate())) < '2018-06-01'
或
SELECT * FROM myTable
WHERE organisation LIKE Ikea
LEAST(case when A = 'NA' THEN getdate() else A end, case when B = 'NA' THEN getdate() else B end, case when C = 'NA' THEN getdate() else C end, case when D = 'NA' THEN getdate() else D end) >= '2018-05-01' AND
LEAST(case when A = 'NA' THEN getdate() else A end, case when B = 'NA' THEN getdate() else B end, case when C = 'NA' THEN getdate() else C end, case when D = 'NA' THEN getdate() else D end) < '2018-06-01'
只需使用coalesce()
:
SELECT *
FROM myTable
WHERE organisation LIKE 'Ikea' 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'
是 在 范围之后的任意日期。
考虑加入使用 UNION ALL
:
派生的聚合查询
SELECT m.*
FROM myTable m
INNER JOIN
(SELECT t.ID, MIN(t.`DateValue`) As MinDate
FROM
(SELECT ID, organisation, 'A' As 'Category', A As `DateValue` FROM myTable
UNION ALL
SELECT ID, organisation, 'B' As 'Category', B As `DateValue` FROM myTable
UNION ALL
SELECT ID, organisation, 'C' As 'Category', C As `DateValue` FROM myTable
UNION ALL
SELECT ID, organisation, 'D' As 'Category', D As `DateValue` FROM myTable) As t
WHERE t.organisation = 'Ikea'
GROUP BY t.ID
HAVING MIN(t.`DateValue`) >= '2018-05-01' AND MIN(t.`DateValue`) < '2018-06-01') As agg
ON m.ID = agg.ID;
RexTester Demo (注意:日期格式为 DD-MM-YYYY)
这是我
table 看起来像这样。
organisation A B C D
Ikea 2018-04-01 2018-05-07 2018-05-09 2018-05-01
Ikea 2018-06-01 2018-05-03 2018-05-29 NA
Orange 2018-04-02 2018-05-01 2018-07-08 2018-05-26
Ikea 2018-06-02 2018-05-01 NA 2018-05-26
Nestle 2018-06-02 2018-05-01 NA 2018-05-26
Ikea NA 2018-05-05 2018-04-02 2018-06-01
我想得到一行,其中组织是宜家,四列(A、B、C、D)中最早的日期在 2018-05-01 和 2018-05-31 之间。
在包含 NA 值的行中,我想忽略 NA 并查看其余值中最早的日期。例如,对于第二行,最早的日期是“2018-05-03”(B列),因此它符合条件。
所以只有原来table上面的第二第四行符合条件。而我想要得到的结果应该是:
organisation A B C D
Ikea 2018-06-01 2018-05-03 2018-05-29 NA
Ikea 2018-06-02 2018-05-01 NA 2018-05-26
我应该如何编写 SQL 查询? 这是我从上一个问题得到答案后的尝试,但它不适用于带有 NA 的行。
SELECT * FROM myTable
WHERE organisation LIKE Ikea
LEAST(A, B, C, D) >= '2018-05-01' AND
LEAST(A, B, C, D) < '2018-06-01'
感谢您的各种帮助!
您可以尝试使用 IFNULL()
作为值并使用 getdate()
所以如果它为 null 它只会在今天使用然后那不会被认为是最少的,这基本上是忽略它们。
赞:LEAST(IFNULL(A,getdate()), IFNULL(B,getdate()), IFNULL(C,getdate()), IFNULL(D,getdate()))
希望这可以将您推向正确的方向
除非 NA
是其中的一个字符串,您可以使用 case when A = 'NA' THEN getdate() end
最终可能看起来像
SELECT * FROM myTable
WHERE organisation LIKE Ikea
LEAST(IFNULL(A,getdate()), IFNULL(B,getdate()), IFNULL(C,getdate()), IFNULL(D,getdate())) >= '2018-05-01' AND
LEAST(IFNULL(A,getdate()), IFNULL(B,getdate()), IFNULL(C,getdate()), IFNULL(D,getdate())) < '2018-06-01'
或
SELECT * FROM myTable
WHERE organisation LIKE Ikea
LEAST(case when A = 'NA' THEN getdate() else A end, case when B = 'NA' THEN getdate() else B end, case when C = 'NA' THEN getdate() else C end, case when D = 'NA' THEN getdate() else D end) >= '2018-05-01' AND
LEAST(case when A = 'NA' THEN getdate() else A end, case when B = 'NA' THEN getdate() else B end, case when C = 'NA' THEN getdate() else C end, case when D = 'NA' THEN getdate() else D end) < '2018-06-01'
只需使用coalesce()
:
SELECT *
FROM myTable
WHERE organisation LIKE 'Ikea' 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'
是 在 范围之后的任意日期。
考虑加入使用 UNION ALL
:
SELECT m.*
FROM myTable m
INNER JOIN
(SELECT t.ID, MIN(t.`DateValue`) As MinDate
FROM
(SELECT ID, organisation, 'A' As 'Category', A As `DateValue` FROM myTable
UNION ALL
SELECT ID, organisation, 'B' As 'Category', B As `DateValue` FROM myTable
UNION ALL
SELECT ID, organisation, 'C' As 'Category', C As `DateValue` FROM myTable
UNION ALL
SELECT ID, organisation, 'D' As 'Category', D As `DateValue` FROM myTable) As t
WHERE t.organisation = 'Ikea'
GROUP BY t.ID
HAVING MIN(t.`DateValue`) >= '2018-05-01' AND MIN(t.`DateValue`) < '2018-06-01') As agg
ON m.ID = agg.ID;
RexTester Demo (注意:日期格式为 DD-MM-YYYY)