除了使用UNION @ UNION ALL之外,在MySQL中合并2个以上的SELECT语句

时间:2014-02-27 04:45:36

标签: mysql sql query-optimization

除了使用SELECTUNION之外,还有其他方法可以在MySQL查询中合并超过2个UNION ALL语句吗?我已尝试使用UNIONUNION ALL但我的查询加载速度太慢。这是我的问题:

SELECT 'AVAILABLE' AS STATUS, count(id_status) as BIL
FROM 
book_records AS b, book_class AS c
WHERE p.id_book = k.id_book AND id_status IN ( 1 ) AND class_desc =  'NOVEL'
UNION
SELECT 'WAITING' AS STATUS, count(id_status) as BIL
FROM 
book_records AS b, book_class AS c
WHERE p.id_book = k.id_book AND id_status IN ( 2,3,5 ) AND class_desc =  'NOVEL'
UNION
SELECT 'DAMAGED' AS STATUS, count(id_status) as BIL
FROM 
book_records AS b, book_class AS c
WHERE p.id_book = k.id_book AND id_status NOT IN ( 1,2,3,5 ) AND class_desc =  'NOVEL'

有谁能告诉我如何解决问题?

1 个答案:

答案 0 :(得分:0)

假设p.id_book = k.id_book实际上意味着b.id_book = c.id_book,您可以尝试以下方法:

SELECT
  STATUS,
  COUNT(*) AS BIL
FROM (
  SELECT
    CASE
      WHEN id_status IN (1)       THEN 'AVAILABLE'
      WHEN id_status IN (2, 3, 5) THEN 'WAITING'
      ELSE                             'DAMAGED'
    END AS STATUS
  FROM
    book_records AS b
  INNER JOIN
    book_class AS c
  ON
    b.id_book = c.id_book
  WHERE
    class_desc =  'NOVEL'
) AS s
GROUP BY
  STATUS
;

可能更好,因为联接的结果集只会被扫描一次。

顺便说一句,在语法上,MySQL允许您在这种情况下避免使用子选择,并将GROUP BY STATUS直接应用于定义STATUS计算列的查询。但是,这不是标准语法,可能很少(如果有的话)其他SQL产品支持它。因此,避免它可能是一个好主意。

此外,关于可维护性和可读性,当查询中涉及多个表时,始终最好使用列来自的表的别名来限定列,即使列名称是唯一的。