这里的想法是GROUP_CONCAT从连接到option_stock和options表的stock表中编译一个选项代码列表,按库存id分组。 一个示例行是这样的:
Name Options Transmission
'Holden Commodore' '111, 145, 166, 188' 'Auto'
这个视图可以正常工作,但我不禁觉得有更优雅的解决方案吗?
CREATE VIEW stock_view AS
(select s.description AS Name,
group_concat(o.option_code order by o.option_code ASC separator ', ')
AS Options,
(case
WHEN group_concat(o.option_code) LIKE '%111%' then 'Auto'
WHEN group_concat(o.option_code) LIKE '%112%' then 'Manual'
else 'Other'
end) as Transmission
from stock s
join option_stock ost ON s.id = ost.stock_id
join options o ON o.id = ost.option_id
group by s.id)
我正试图避免在CASE困境中使用这个丑陋的看起来的GROUP_CONCAT,但是如果我在case语句中使用它,那么我会收到一条错误,说明Options
字段不存在:
WHEN `Options` LIKE '%111%' then 'Auto'
我知道为什么会抛出错误 - 这是因为你不能以这种方式使用另一列的别名。但它有办法吗?
答案 0 :(得分:1)
这些对我来说似乎不够可靠:
WHEN group_concat(o.option_code) LIKE '%111%' ...
WHEN group_concat(o.option_code) LIKE '%112%' ...
LIKE '%111%'
会匹配,例如'111222, 145, 166, 188'
和'111, 145, 166, 188'
一样{。}}。当然,除非只有3个字符的代码,否则您不希望很快改变。
尽管如此,我可能会使用不同的技术,很可能是条件COUNT或SUM。例如:
(CASE
WHEN SUM(o.option_code = '111') > 0 THEN 'Auto'
WHEN SUM(o.option_code = '112') > 0 THEN 'Manual'
ELSE 'Other'
END) AS Transmission
另请注意,在您的特定情况下,以下(尽管相当具体)解决方案也应该起作用:
IFNULL(
MIN(CASE o.option_code WHEN '111' THEN 'Auto' WHEN '112' THEN 'Manual' END),
'Other'
) AS Transmission
即。如果'111'
或由于某种原因在同一组行的代码中找到'111'
和'112'
,则MIN()
将返回'Auto'
,如果'112'
僵尸不是'111'
,它将评估为'Manual'
。否则它将为NULL,在这种情况下IFNULL()
函数将评估为'Other'
。
答案 1 :(得分:0)
很难在没有实际表的情况下进行测试(实际上不能执行语句)但是这样的事情呢?
CREATE VIEW stock_view AS
(SELECT
gc.Name,
gc.Options,
(case
WHEN gc.Options LIKE '%111%' then 'Auto'
WHEN gc.Options LIKE '%112%' then 'Manual'
else 'Other'
end) as Transmission
FROM
(select
s.description AS Name,
group_concat(o.option_code order by o.option_code ASC separator ', ') AS Options
from
stock s
join option_stock ost ON s.id = ost.stock_id
join options o ON o.id = ost.option_id
group by
s.id) gc);
答案 2 :(得分:0)
进行单独的连接以确定传输类型:
CREATE VIEW stock_view AS
select
s.description AS Name,
group_concat(o.option_code order by o.option_code separator ', ') AS Options,
if(t.option_code = '111', 'Auto', 'Manual') as Transmission
from stock s
join option_stock ost ON s.id = ost.stock_id
join options o ON o.id = ost.option_id
left join options t on t.id = ost.option_id
and option_code in ('111', '112')
group by s.id
只有一行将从传输连接中加入(汽车不能同时为自动和手动),这种方法可以避免所有这些子查询。
使连接成为 left 连接意味着缺少传输选项将显示为手动。您可以通过添加null测试来调整它以获得默认值。
答案 3 :(得分:0)
您必须创建两个单独的 VIEWS ,因为 MySQL 不支持 VIEW 中的子查询。
试试这个:
CREATE VIEW stock_view AS
SELECT s.description AS sname,
GROUP_CONCAT(o.option_code ORDER BY o.option_code SEPARATOR ', ') AS soptions
FROM stock s
INNER JOIN option_stock ost ON s.id = ost.stock_id
INNER JOIN OPTIONS o ON o.id = ost.option_id
GROUP BY s.id;
CREATE VIEW stock_view1 AS
SELECT sname, soptions,
(CASE WHEN FIND_IN_SET('111', soptions) THEN 'Auto'
WHEN FIND_IN_SET('112', soptions) THEN 'Manual'
ELSE 'Other'
END) AS Transmission
FROM stock_view;