仅当字段不为NULL时才对MySQL条目进行分组,否则使用CASE对另一个字段进行分组

时间:2014-12-05 11:16:27

标签: mysql sql group-by case

我有一个books表,用于存储书籍版本。通常,在我的数据库中多次插入同一本​​书,因为它以不同的形式存在(精装本,平装本,电子书等)。每本书都有以下领域(其中包括):

  • id(这是一个唯一的主键)
  • title
  • 项目(这是一个int,同一本书的两种不同形式将具有相同的项目,预订 只存在于一个表单中的将是NULL)

现在,如果有另一个sales表存储销售额并且看起来像这样:

  • id(唯一主键)
  • book_id(与book.id有关)
  • 日期(销售发生的日期)

我需要获得畅销书的列表,将书籍的不同版本分组,好像有相同的书,所以我的SQL查询看起来像:

    SELECT `books`.`title`, COUNT(`sales`.`id`) 
    FROM `sales` 
    JOIN `books` ON `books`.`id` = `sales`.`book_id` 
    GROUP BY (CASE WHEN `item` IS NOT NULL THEN `item` ELSE `books`.`id` END)

问题在于,具有id 27057和项目NULL的书“Margherita Dolcevita”与具有id 49522和项目27057的“风暴大师”一书分组。

我需要在我的sql查询(最好)或我的数据库方案中更改什么才能通过一个查询获得我想要的内容?

1 个答案:

答案 0 :(得分:2)

问题出在CASE子句的GROUP BY上。你在那里混合" item"用" id"。

理想情况下,您应该为books表格中的任何图书保留一个条目,并为包含这些字段的图书格式设置不同的表格:

  • id(PK,autoincrement);
  • book_id(FK,booksid);
  • 格式(整数,字符串,适合您的设计);

使用您当前的设计,尝试使您在CASE表达式中使用的两个ID的范围不重叠(fe为books添加前缀。id):< / p>

GROUP BY (CASE WHEN `item` IS NOT NULL THEN `item` ELSE CONCAT('book-', `books`.`id`) END)

同一表达式的一个更简单的形式(更容易阅读和理解)是:

GROUP BY IFNULL(`item`, CONCAT('book-', `books`.`id`))