SQL 多条件 CASE WHEN 问题
SQL Multi Conditional CASE WHEN issues
我在以下情况下尝试使用 CASE WHEN 时遇到问题:
我有一个超过 3 列的 table,但这 3 列是唯一相关的:order_number、payment_method、order_date.
每个 order_number 可以有多个“订单”。永远不会有两个相同的order_date
Order Number
Payment Method
Order Date
120
Cash
01/01/2021
175
Credit Card
01/02/2021
209
Cash
01/03/2021
209
Credit Card
01/04/2021
209
Personal Check
01/05/2021
209
Credit Card
01/06/2021
209
Cash
01/07/2021
209
Personal Check
01/08/2021
277
Credit Card
01/09/2021
301
Cash
01/10/2021
333
Personal Check
01/11/2021
333
Cash
01/12/2021
333
Cash
01/13/2021
333
Personal Check
01/14/2021
400
Credit Card
01/15/2021
551
Credit Card
01/16/2021
551
Cash
01/17/2021
680
Personal Check
01/18/2021
我正在尝试合并它,以便我有一个每个订单号只有 1 行的列表,基于以下逻辑:
- 如果只有1个订单号-return订单日期
- 如果有 >1 个相似的订单号,并且这些订单中有任何一个是用信用卡支付的 - return最近一次用信用卡支付的订单日期
- 如果有 >1 个相似的订单号并且 none 的订单是使用信用卡支付的 - return 最近的订单日期。
目标看起来像这样:
Order Number
Payment Method
Order Date
120
Cash
01/01/2021
175
Credit Card
01/02/2021
209
Credit Card
01/06/2021
277
Credit Card
01/09/2021
301
Cash
01/10/2021
333
Personal Check
01/14/2021
400
Credit Card
01/15/2021
551
Credit Card
01/16/2021
680
Personal Check
01/18/2021
没有重复的订单号,当有重复的订单号时,按照逻辑拉取那一行。
我尝试了CASE WHEN的各种方法,但是在THEN部分应用条件时总是失败。
也许这样的事情会奏效:
SELECT o.order_number, MAX(COALESCE(tc.latest_cc_tran, o.order_date)) AS latest_date
FROM order o
OUTER APPLY(
SELECT MAX(ot.tran_date) latest_cc_tran
FROM order_tran ot
WHERE ot.order_number = o.order_number
) tc
GROUP BY o.order_number
注意:我没有测试查询,但它应该传达了要点。
作为一般方法,您可以使用 row_number()
:
select o.*
from (select o.*,
row_number() over (partition by order_number
order by (case when payment_method = 'Credit Card' then 1 else 2 end),
order_date desc
) as seqnum
from orders o
) o
where seqnum = 1;
这是通用的 SQL,应该适用于任何数据库。但是,根据您的数据库,可能会有快捷方式。
我在以下情况下尝试使用 CASE WHEN 时遇到问题:
我有一个超过 3 列的 table,但这 3 列是唯一相关的:order_number、payment_method、order_date.
每个 order_number 可以有多个“订单”。永远不会有两个相同的order_date
Order Number | Payment Method | Order Date |
---|---|---|
120 | Cash | 01/01/2021 |
175 | Credit Card | 01/02/2021 |
209 | Cash | 01/03/2021 |
209 | Credit Card | 01/04/2021 |
209 | Personal Check | 01/05/2021 |
209 | Credit Card | 01/06/2021 |
209 | Cash | 01/07/2021 |
209 | Personal Check | 01/08/2021 |
277 | Credit Card | 01/09/2021 |
301 | Cash | 01/10/2021 |
333 | Personal Check | 01/11/2021 |
333 | Cash | 01/12/2021 |
333 | Cash | 01/13/2021 |
333 | Personal Check | 01/14/2021 |
400 | Credit Card | 01/15/2021 |
551 | Credit Card | 01/16/2021 |
551 | Cash | 01/17/2021 |
680 | Personal Check | 01/18/2021 |
我正在尝试合并它,以便我有一个每个订单号只有 1 行的列表,基于以下逻辑:
- 如果只有1个订单号-return订单日期
- 如果有 >1 个相似的订单号,并且这些订单中有任何一个是用信用卡支付的 - return最近一次用信用卡支付的订单日期
- 如果有 >1 个相似的订单号并且 none 的订单是使用信用卡支付的 - return 最近的订单日期。
目标看起来像这样:
Order Number | Payment Method | Order Date |
---|---|---|
120 | Cash | 01/01/2021 |
175 | Credit Card | 01/02/2021 |
209 | Credit Card | 01/06/2021 |
277 | Credit Card | 01/09/2021 |
301 | Cash | 01/10/2021 |
333 | Personal Check | 01/14/2021 |
400 | Credit Card | 01/15/2021 |
551 | Credit Card | 01/16/2021 |
680 | Personal Check | 01/18/2021 |
没有重复的订单号,当有重复的订单号时,按照逻辑拉取那一行。
我尝试了CASE WHEN的各种方法,但是在THEN部分应用条件时总是失败。
也许这样的事情会奏效:
SELECT o.order_number, MAX(COALESCE(tc.latest_cc_tran, o.order_date)) AS latest_date
FROM order o
OUTER APPLY(
SELECT MAX(ot.tran_date) latest_cc_tran
FROM order_tran ot
WHERE ot.order_number = o.order_number
) tc
GROUP BY o.order_number
注意:我没有测试查询,但它应该传达了要点。
作为一般方法,您可以使用 row_number()
:
select o.*
from (select o.*,
row_number() over (partition by order_number
order by (case when payment_method = 'Credit Card' then 1 else 2 end),
order_date desc
) as seqnum
from orders o
) o
where seqnum = 1;
这是通用的 SQL,应该适用于任何数据库。但是,根据您的数据库,可能会有快捷方式。