MySQL' where case'仅适用于某些价值

时间:2016-12-28 14:44:26

标签: mysql

我有下表:

id | date_inserted | type       | route_id | route_type | km
1    2016-01-05      Transport    null       Normal       null
2    2016-01-06      Transport    null       Normal       50
3    2016-01-07      Transport    1          Normal       null
4    2016-04-02      Transport    2          Normal       null
5    2016-05-03      Services     null       Normal       20
6    2016-06-21      Transport    null       Exceptional  35

我需要按月检索总路线数。这是通过以下方式完成的:

SELECT type, COUNT(id) AS `total`, MONTH(date_inserted) AS `month`
FROM routes
WHERE YEAR(date_inserted) = '2016' AND 
      type IN ('Transport', 'Services')
GROUP BY type, `month`
ORDER BY date_inserted ASC, `total` DESC

输出类似于:

type       | total | month
Transport    3       1
Transport    1       2
Services     1       5
Transport    1       6

它工作正常。但是,现在我被要求仅在类型为Transport时应用某些条件,条件如下:

  1. route_id不能为空或
  2. route_type必须为Exceptional
  3. route_typeNormalkm不等于零
  4. 所以,根据这个条件,这就是我尝试过的:

    SELECT type, COUNT(id) AS `total`, MONTH(date_inserted) AS `month`
    FROM routes
    WHERE YEAR(date_inserted) = '2016' AND 
          type IN ('Transport', 'Services') AND 
          (CASE WHEN type = 'Transport' THEN 
                route_id IS NOT NULL OR
                route_type = 'Exceptional' OR 
                (route_type = 'Normal' AND km != 0)
          END)
    GROUP BY type, `month`
    ORDER BY date_inserted ASC, `total` DESC
    

    但我的输出是:

    type       | total | month
    Transport    2       1
    Transport    1       2
    Transport    1       6
    

    缺少Services行。

2 个答案:

答案 0 :(得分:1)

您需要添加一个else段来处理服务。如果您希望案例为“是”,则允许正常处理使用1 = 1。

SELECT type, COUNT(id) AS `total`, MONTH(date_inserted) AS `month`
FROM routes
WHERE YEAR(date_inserted) = '2016' AND 
  type IN ('Transport', 'Services') AND 
  (CASE WHEN type = 'Transport' THEN 
        route_id IS NOT NULL OR
        route_type = 'Exceptional' OR 
        (route_type = 'Normal' AND km != 0)
  ELSE 
  1 = 1
  END)
GROUP BY type, `month`
ORDER BY date_inserted ASC, `total` DESC

答案 1 :(得分:1)

正如其他人所说,您需要在案例中添加ELSE,否则当该行是“服务”时。它将返回null并且不显示记录。

SELECT type, COUNT(id) AS `total`, MONTH(date_inserted) AS `month`
FROM routes
WHERE YEAR(date_inserted) = '2016' AND 
      type IN ('Transport', 'Services') AND 
      (CASE WHEN type = 'Transport' THEN 
            route_id IS NOT NULL OR
            route_type = 'Exceptional' OR 
            (route_type = 'Normal' AND km != 0) 
            ELSE 1 = 1
      END)
GROUP BY type, `month`
ORDER BY date_inserted ASC, `total` DESC;

您可以使用的另一个版本(我更喜欢)是:

SELECT type, COUNT(id) AS `total`, MONTH(date_inserted) AS `month`
FROM routes
WHERE YEAR(date_inserted) = '2016' AND 
      (type = 'Services' OR 
            (type = 'Transport' and 
                    (route_id IS NOT NULL OR
                        route_type = 'Exceptional' OR 
                        (route_type = 'Normal' AND km != 0)
                    )
        )
      )
GROUP BY type, `month`
ORDER BY date_inserted ASC, `total` DESC;

如果route_type只能NormalExceptional,您可以更改条件:

SELECT type, COUNT(id) AS `total`, MONTH(date_inserted) AS `month`
FROM routes
WHERE YEAR(date_inserted) = '2016' AND 
      (type = 'Services' OR 
            (type = 'Transport' and 
                    (route_id IS NOT NULL OR
                     route_type = 'Exceptional' OR 
                     km != 0
                    )
        )
      )
GROUP BY type, `month`
ORDER BY date_inserted ASC, `total` DESC;