简体   繁体   English

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

[英]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 min Cancellation_Policy_Hours which correspond to the Free Cancellation (if exists)与免费取消对应的最小 Cancellation_Policy_Hours(如果存在)
  • if the above doesn't exist for the specific ID, then I want to check if there is a partially refundable如果以上不存在特定ID,那么我想检查是否有部分可退还的
  • if none of the above exist, then check if there is No Refundable.如果以上都不存在,则查看是否有No Refundable。

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 ID Cancellation_Policy_Type取消政策类型 Cancellation_Policy_Hours取消政策_营业时间
1 1个 No Refundable不可退款 17520 17520
1 1个 Partially Refunable部分可退还 168 168
1 1个 Free Cancellation免费取消 96 96
2 2个 No Refundable不可退款 17520 17520
2 2个 Partially Refunable部分可退还 336 336
2 2个 Free Cancellation免费取消 48 48
3 3个 No Refundable不可退款 17520 17520
3 3个 Partially Refunable部分可退还 336 336
4 4个 No Refundable不可退款 17520 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 ID Most Flexible Cancellation Type最灵活的取消类型 Most Flexible Cancellation Hours最灵活的取消时间 Other Columns (including buckets)其他列(包括桶)
1 1个 Free Cancellation免费取消 96 96 a一种
1 1个 Free Cancellation免费取消 96 96 b b
1 1个 Free Cancellation免费取消 96 96 c c
2 2个 Free Cancellation免费取消 48 48 a一种
2 2个 Free Cancellation免费取消 48 48 b b
2 2个 Free Cancellation免费取消 48 48 c c
3 3个 Partially Refunable部分可退还 336 336 a一种
3 3个 Partially Refunable部分可退还 336 336 b b
3 3个 Partially Refunable部分可退还 336 336 c c
4 4个 No Refundable不可退款 17520 17520 a一种
4 4个 No Refundable不可退款 17520 17520 b b
4 4个 No Refundable不可退款 17520 17520 c 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.

相关问题 Mysql Insert ColumnName是(从同一表的另一列中选择值) - Mysql Insert ColumnName is (SELECT value form another column of the same table) mysql如何选择在另一列中具有相同值且在另一表的列中具有相同值的字段? - mysql How to select fields that have the same value in another column AND the same value in another table's column? MYSQL:如何根据另一个表中的数据选择列? - MYSQL: How do select column depending on data from another table? MYSQL-将一列复制到同一表中的另一列-有条件 - MYSQL - copy one column to another in the same table - with conditions MySQL根据另一个表选择表中的值 - MySQL Select values in table depending on another table 根据MySQL语句中的另一个表列动态确定列值 - Determine column value dynamically based on another table column in MySQL statement MySQL Select 语句使用相同的表和列但别名不同的名称 - MySQL Select Statement using the same table and column but different names for an alias SELECT 列的值不在同一个表的另一列中 MySQL - SELECT values of a column that are not in another column in the same table MySQL MySQL根据列值选择多列 - MySQL Select multiple column depending on column value 选择同一表的另一列“ MySQL数据库不存在”子句中不存在的值 - Select value that does not exist in another column of the same table, MySQL Database Not Exists Clause
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM