带有取决于另一列值的条件的Select语句-相同表(mysql)

fcg9iug3  于 2022-11-21  发布在  Mysql
关注(0)|答案(2)|浏览(146)

我有一个包含3列表:

ID, 
Cancellation_Policy_Type 
Cancellation_Policy_Hours.

我想获得的查询将允许我选择:

  • 对应于免费取消的最小Cancellation_Policy_Hours(如果存在)
  • 如果上述不存在的具体ID,那么我想检查是否有一个部分退款
  • 如果以上都不存在,则检查是否存在“不可退款”。

下面的查询是不正确的,但它可能会给予一个更好的想法,我试图实现什么:

IF (SELECT ID, Cancellation_Policy_Type, MIN(Cancellation_Policy_Hours) from MYTABLE WHERE Cancellation_Policy_Type = 'Free Cancellation') IS NOT NULL)
THEN (SELECT ID, Cancellation_Policy_Type, MIN(Cancellation_Policy_Hours) from MYTABLE WHERE Cancellation_Policy_Type = 'Free Cancellation')
ELSEIF (SELECT ID, Cancellation_Policy_Type, MIN(Cancellation_Policy_Hours) from MYTABLE WHERE Cancellation_Policy_Type = 'Free Cancellation') IS NULL AND (SELECT ID, Cancellation_Policy_Type, MIN(Cancellation_Policy_Hours  from MYTABLE WHERE Cancellation_Policy_Type = 'Partially Refundable') IS NOT NULL Then (SELECT ID, Cancellation_Policy_Type, MIN(Cancellation_Policy_Hours) from MYTABLE WHERE Cancellation_Policy_Type = 'Partially Refundable')
ELSEIF (SELECT ID, Cancellation_Policy_Type, MIN(Cancellation_Policy_Hours) from MYTABLE WHERE Cancellation_Policy_Type = 'Free Cancellation') IS NULL AND (SELECT ID, Cancellation_Policy_Type, MIN(Cancellation_Policy_Hours) from MYTABLE WHERE Cancellation_Policy_Type = 'Partially Refundable') IS NULL  THEN (SELECT ID, Cancellation_Policy_Type, MIN(Cancellation_Policy_Hours) from MYTABLE WHERE Cancellation_Policy_Type = 'No Refundable') 
END

下面是我的数据集示例:
该表包含了每个ID的取消政策的所有数据:
| 识别码|取消政策类型|取消政策小时数|
| - -|- -|- -|
| 一个|不退款|小行星17520|
| 一个|部分退款|一百六十八|
| 一个|免费取消|九十六个|
| 2个|不退款|小行星17520|
| 2个|部分退款|三百三十六|
| 2个|免费取消|四十八|
| 三个|不退款|小行星17520|
| 三个|部分退款|三百三十六|
| 四个|不退款|小行星17520|
下面是所需的结果,即包含其他信息(包括生产)和2列的表,其中每个ID重复最佳可用的取消政策类型和小时:
| 识别码|最灵活的取消类型|最灵活的取消时间|其它列(包括存储桶)|
| - -|- -|- -|- -|
| 一个|免费取消|九十六|一种|
| 一个|免费取消|九十六|B|
| 一个|免费取消|九十六|C语言|
| 2个|免费取消|四十八|一种|
| 2个|免费取消|四十八|B|
| 2个|免费取消|四十八|C语言|
| 三个|部分退款|三百三十六|一种|
| 三个|部分退款|三百三十六|B|
| 三个|部分退款|三百三十六|C语言|
| 四个|不退款|小行星17520|一种|
| 四个|不退款|小行星17520| B|
| 四个|不退款|小行星17520| C语言|

SELECT
a.ID
, Most_Flexible_Policy_Type 
, Most_Flexible_Cancellation_Hours
, a.BookingWindowBuckets
FROM Production a
LEFT JOIN Property b on a.ID = b.ID
GROUP BY
1,2,3,4

谢谢你

7rfyedvj

7rfyedvj1#

我知道,对于production中的每一行,您都希望从表property中获取保单小时数最少的取消保单。
我们可以使用窗口函数来对每个id的策略和production的连接进行排序:

select d.id, 
    p.cancellation_type_policy  most_flexible_cancellation_type,
    p.cancellation_policy_hours most_flexible_cancellation_hours
from production d
inner join (
    select p.*, row_number() over(partition by id order by cancellation_policy_hours) rn
    from property p
) p on p.id = d.id
where rn = 1
ybzsozfc

ybzsozfc2#

你没有提供足够的信息来帮助你确信这是“正确”的方法,但是(在这里猜测)你可以尝试-

SELECT
    ID,
    MIN(IF(Cancellation_Policy_Type = 'Free Cancellation', Cancellation_Policy_Hours, NULL)) AS minFreeCancellation,
    MIN(IF(Cancellation_Policy_Type = 'Partially Refundable', Cancellation_Policy_Hours, NULL)) AS minPartiallyRefundable,
    MIN(IF(Cancellation_Policy_Type = 'No Refundable', Cancellation_Policy_Hours, NULL)) AS minNoRefundable
FROM MYTABLE
WHERE ID = ?
GROUP BY ID;

如果您以完整数据表结构(CREATE陈述式)、一些范例数据、一些统计数据和所需结果的形式提供范例,您就更有可能得到“正确”的答案。上述条件式汇总范例可能不是最佳的方式,但它可能会提供您所要寻找的内容。根据您的数据集而定,只执行个别查询可能是最佳的解决方案。

UPDATE以下是使用窗口函数(MySQL 8)执行此操作的一种方法-

WITH Properties (ID, Cancellation_Policy_Type, Cancellation_Policy_Hours, Most_Flexible) AS (
    SELECT
        ID, Cancellation_Policy_Type, Cancellation_Policy_Hours,
        ROW_NUMBER() OVER (PARTITION BY ID ORDER BY
            CASE Cancellation_Policy_Type
                WHEN 'Free Cancellation' THEN 0
                WHEN 'Partially Refundable' THEN 1
                WHEN 'No Refundable' THEN 2
            END ASC, Cancellation_Policy_Hours ASC
        )
    FROM Property
)
SELECT
    a.ID,
    b.Cancellation_Policy_Type,
    b.Cancellation_Policy_Hours,
    a.BookingWindowBuckets
FROM Production a
LEFT JOIN Properties b on a.ID = b.ID
WHERE b.Most_Flexible = 1;

相关问题