【问题标题】:How to use an if condition in a query?如何在查询中使用 if 条件?
【发布时间】:2018-07-23 10:15:10
【问题描述】:

假设如果所有matches 的状态设置为3,我想选择matchesMAX 游戏周,或者matchesMIN 游戏周我该怎么做?

数据样本

id | status | gameweek | round_id 
 1     3         3          1
 2     3         3          1
 3     1         3          1
 4     1         4          1
 5     1         4          1
 6     1         4          1

最终结果应该是:1, 2, 3,因为并非所有比赛都已进行。 我能够为MAX 设置查询:

SELECT MAX(gameweek) FROM `match` m WHERE round_id = 1 AND m.status = 3

但是我有一些难以实现的 IF 条件,有人可以帮助我吗?

谢谢。

更新

在用户提出的解决方案中,我注意到我没有很好地解释一个特定情况:如果一轮的所有比赛都没有状态 3,则查询应该返回 round_id 的 MIN(gameweek)指定。

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    如果我做对了,您可以使用CASE。如果存在具有status 而不是3 的记录,则返回最小值gameweek,否则返回最大值。将结果与gameweek 进行比较。

    SELECT `m1`.*
           FROM `match` `m1`
           WHERE `m1`.`round_id` = 1
                 AND `m1`.`gameweek` = CASE
                                         WHEN EXISTS (SELECT *
                                                             FROM `match` `m2`
                                                             WHERE `m2`.`round_id` = `m1`.`round_id`
                                                                   AND `m2`.`status` <> 3) THEN
                                           (SELECT min(`m3`.`gameweek`)
                                                   FROM `match` `m3`
                                                   WHERE `m3`.`round_id` = `m1`.`round_id`)
                                         ELSE
                                           (SELECT max(`m4`.`gameweek`)
                                                   FROM `match` `m4`
                                                   WHERE `m4`.`round_id` = `m1`.`round_id`)
                                       END;
    

    我不确定您是否想将其限制为某个round_id。它在您的查询中,但不在文本中。如果不想要,把round_id相关的条件全部去掉。


    编辑:

    要使用最大值gameweek,如果不是所有status 等于3 和最小值gameweek,否则您可以检查status 的最小值是否等于最大值(即所有状态都是相同),如果它等于 3。

    SELECT `m1`.*
           FROM `match` `m1`
           WHERE `m1`.`round_id` = 1
                 AND `m1`.`gameweek` = CASE
                                         WHEN EXISTS (SELECT min(`m2`.`status`)
                                                             FROM `match` `m2`
                                                             WHERE `m2`.`round_id` = `m1`.`round_id`
                                                             HAVING min(`m2`.`status`) <> max(`m2`.`status`)
                                                                    OR min(`m2`.`status`) <> 3) THEN
                                           (SELECT min(`m3`.`gameweek`)
                                                   FROM `match` `m3`
                                                   WHERE `m3`.`round_id` = `m1`.`round_id`)
                                         ELSE
                                           (SELECT max(`m4`.`gameweek`)
                                                   FROM `match` `m4`
                                                   WHERE `m4`.`round_id` = `m1`.`round_id`)
                                       END;
    

    【讨论】:

    • @Charanoglu:我有,它对我有用,因为我理解你的问题。但是由于您没有提供 DDL 或 DML,我的设置可能有所不同。考虑在问题中提供 DDL 和 DML 以及更多示例数据和所需结果,可能适用于两种(或所有)情况。
    • 我得到:4 errors were found during the analysis. Keyword not recognized. (near "CASE" in position 99) Keyword not recognized. (near "WHEN" in position 119) Keyword not recognized. (near "EXISTS" in position 124) Unexpected token. (near "(" to position 131)
    • @Charanoglu:您是否更改或嵌入了某处?语法是可以的(单独)。
    • 我只是将您的查询粘贴到 phpmyadmin 中,并将 round_id 更改为我自己的 1293 而不是 1,我没有更改语法
    • @Charanoglu 也许您的数据库中没有round_id 1293。此外,我不建议在更大的表上使用此查询,因为相关的子查询往往在 MySQL 上优化得非常糟糕.
    【解决方案2】:

    假设可以有多个round_id

    SELECT *
    FROM `match` m 
    WHERE (gameweek, round_id ) = 
    (
      SELECT MAX(gameweek),round_id 
      FROM `match` m 
      WHERE round_id = 1 AND m.status = 3
      GROUP BY round_id
    )
    

    DBFiddle DEMO

    【讨论】:

    • 感谢您的回答,我尝试了您的查询但返回一个空结果,您尝试过吗?
    • @Charanoglu 我已经添加了演示
    • 等等我忽略了the status = 3我真的需要一些咖啡我要赎回我的最后一条评论......“因为子查询返回对(3,1)。”不子查询只会返回一条记录记录,因为没有GROUP BY,并且此查询将在启用ONLY_FULL_GROUP_BY 的sql 模式下失败,因为您将非聚合列与没有GROUP BY 的聚合列混合在一起,这实际上是无效的SQL,请参见演示@987654322 @@Charanoglu 确保在子查询中添加 GROUP BY
    • @RadimBača 好的,如果状态 = 3 匹配,这似乎有效,但如果没有与该状态匹配,则不会返回任何内容,而是查询应返回 MIN(gameweek)
    • @RaymondNijland 你是对的,没有GROUP BY 的结果有点随机......我已经添加了它。我可能也需要一杯咖啡:)
    【解决方案3】:

    好吧,比我想象的要简单,我发现我可以使用COALESCE操作符来实现这个目标,所以:

    m.gameweek = (SELECT COALESCE(MIN(
                        CASE WHEN m2.status < 3 
                             THEN m2.gameweek END), 
                       MAX(m2.gameweek))
                       FROM `match` m2 
                       WHERE m2.round_id = m.round_id)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-08
      • 1970-01-01
      • 2016-03-08
      • 1970-01-01
      • 2012-04-05
      • 1970-01-01
      相关资源
      最近更新 更多