LEFT JOIN vs IF vs CASE vs SUBSELECTS

时间:2014-08-28 19:23:21

标签: mysql

SELECT

`model`,
`name`,
`category`,
`price`

FROM   `books`

我想从:

********************************************************************
*       model | name | category  | price          
********************************************************************
*       x     | y    | categoryA | price
*       b     | d    | categoryB | price
*       y     | u    | categoryB | price
*       d     | u    | categoryA | price
*       d     | u    | categoryB | price
*       d     | u    | categoryC | price

为:

********************************************************************
*       model | name | categoryA price | categoryB price | categoryC price       
********************************************************************
*       x     | y    | price cat A     | NULL            | NULL
*       b     | d    | NULL            | price cat B     | NULL
*       y     | u    | NULL            | price cat B     | NULL
*       d     | u    | price cat A     | price cat B     | NULL

我想将模型和名称组合在一起并显示相应的价格。

我尝试过使用左连接,子选择,大小写,if等等...我正在尝试找到最有效的方式。

SELECT

`model`,
`name`,
(
case
when `category` = 'CategoryA'
then `price`
end
) as `CategoryA Price`,

(
case
when `category` = 'CategoryB'
then `price`
end
) as `CategoryB Price`

FROM   `books`

GROUP BY `model`,`name`

但是,我没有得到想要的结果。

我希望这个蹩脚的例子让我的观点得到了解决。

谢谢

3 个答案:

答案 0 :(得分:2)

您需要一个聚合功能。我认为max()会起作用:

SELECT `model`, `name`,
        max(case when `category` = 'CategoryA' then `price` end) as `CategoryA Price`,
        max(case when `category` = 'CategoryB' then `price` end) as `CategoryB Price`,
FROM   `books`
GROUP BY `model`, `name`;

答案 1 :(得分:0)

我认为您需要的是一个数据透视表。由于MySQL没有这样做的指令,你必须“手动”构建它......但它并不像听起来那么难:

-- First you need to build the column list.
-- The "CASE ... END" expression will filter the data for each column
-- I use "max()" as an example; use whatever aggregate function you need.
select
  group_concat(distinct
    concat(
      'max(case when category = ', del_productID, ' then price end) ',
      'as `category_', category, '` '
    )
  )
into @sql
from books;

-- Now build the full SELECT statement
set @sql = concat('SELECT model, name, ', @sql, ' from books group by model, name');


-- OPTIONAL: Check the SELECT statement you've just built
select @sql;

-- Prepare a statement using the SELECT statement built above
prepare stmt from @sql;
execute stmt;

-- When you are done, be sure to dealocate the prepared statement
deallocate prepare stmt;

有关示例,请参阅herehere


如果category列的内容没有改变(即你的类别已经存在且不会有更多),Gordon Linoff的回答就足够了。但是如果随着时间的推移可以有更多的类别,那么数据透视表就是最佳选择。

答案 2 :(得分:0)

我认为你可以通过 self 加入来做到这一点,假设你没有不合理数量的类别。

select
  book.model, book.name, A.price, B.price, C.price
from
  books as book
  left join books as A
    on book.model = A.model 
    and book.name = A.name
    and A.category = 'categoryA'
  left join books as B
    on book.model = B.model 
    and book.name = B.name
    and B.category = 'categoryB'
  left join books as C
    on book.model = C.model 
    and book.name = C.name
    and C.category = 'categoryC'