[英]Select statement with conditions depending on the value of another column - same table (mysql)
I have table with 3 columns:我有 3 列的表:
ID,
Cancellation_Policy_Type
Cancellation_Policy_Hours.
The query I would like to get to will allow me to select:我想查询的查询将允许我访问 select:
The below query is not correct but it may give a better idea about what I am trying to achieve:下面的查询不正确,但它可以让我更好地了解我想要实现的目标:
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
Below you will find an example of my dataset:您将在下面找到我的数据集的示例:
This is the table which contains all data regarding the cancellation policies of every single ID:这是包含有关每个 ID 取消政策的所有数据的表格:
ID ![]() |
Cancellation_Policy_Type![]() |
Cancellation_Policy_Hours![]() |
---|---|---|
1 ![]() |
No Refundable![]() |
17520 ![]() |
1 ![]() |
Partially Refunable![]() |
168 ![]() |
1 ![]() |
Free Cancellation![]() |
96 ![]() |
2 ![]() |
No Refundable![]() |
17520 ![]() |
2 ![]() |
Partially Refunable![]() |
336 ![]() |
2 ![]() |
Free Cancellation![]() |
48 ![]() |
3 ![]() |
No Refundable![]() |
17520 ![]() |
3 ![]() |
Partially Refunable![]() |
336 ![]() |
4 ![]() |
No Refundable![]() |
17520 ![]() |
Below is the desired result, that is a table which contains other pieces of information (including production) and the 2 columns where for every single ID repeats the best available cancellation policy type and hours:下面是期望的结果,这是一个包含其他信息(包括生产)的表格和 2 列,其中每个 ID 重复最佳可用取消政策类型和时间:
ID ![]() |
Most Flexible Cancellation Type![]() |
Most Flexible Cancellation Hours![]() |
Other Columns (including buckets)![]() |
---|---|---|---|
1 ![]() |
Free Cancellation![]() |
96 ![]() |
a![]() |
1 ![]() |
Free Cancellation![]() |
96 ![]() |
b ![]() |
1 ![]() |
Free Cancellation![]() |
96 ![]() |
c ![]() |
2 ![]() |
Free Cancellation![]() |
48 ![]() |
a![]() |
2 ![]() |
Free Cancellation![]() |
48 ![]() |
b ![]() |
2 ![]() |
Free Cancellation![]() |
48 ![]() |
c ![]() |
3 ![]() |
Partially Refunable![]() |
336 ![]() |
a![]() |
3 ![]() |
Partially Refunable![]() |
336 ![]() |
b ![]() |
3 ![]() |
Partially Refunable![]() |
336 ![]() |
c ![]() |
4 ![]() |
No Refundable![]() |
17520 ![]() |
a![]() |
4 ![]() |
No Refundable![]() |
17520 ![]() |
b ![]() |
4 ![]() |
No Refundable![]() |
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
Thank you谢谢
I understand that, for each row in production
, you want to bring from table property
the cancellation policy with the least policy hours.我知道,对于
production
中的每一行,您想从表property
中获取政策时间最少的取消政策。
We can do this with window functions to rank the policies of feach id
, and a join to production
:我们可以使用 window 函数对 feach
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
You have not given enough information to be able to help you with any degree of confidence that it is the "right" way but (guessing here) you could try -您没有提供足够的信息来帮助您确信这是“正确”的方式,但是(在这里猜测)您可以尝试 -
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;
If you provide an example in the form of full table structure (CREATE statement), some sample data, some stats and the desired outcome you are more likely to get the "right" answer.如果您以完整表结构(CREATE 语句)、一些示例数据、一些统计信息和期望结果的形式提供示例,您更有可能获得“正确”答案。 The above example of conditional aggregation is unlikely to be the best way to do it but it will probably provide what you are looking for.
上面的条件聚合示例不太可能是最好的方法,但它可能会提供您正在寻找的内容。 Depending on your dataset, just running the separate queries may be the best solution.
根据您的数据集,仅运行单独的查询可能是最佳解决方案。
UPDATE Here is one way of doing this using a window function (MySQL 8) -更新这是使用 window function (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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.