4

这里的想法是 GROUP_CONCAT 从连接到 option_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,但是Options如果我在这样的 case 语句中使用它,我会收到一个错误,指出该字段不存在:

WHEN `Options` LIKE '%111%' then 'Auto'

我知道为什么会抛出错误 - 这是因为您不能以这种方式使用另一列的别名。但是有办法解决吗?

4

4 回答 4

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'将返回,如果bot 不是,则计算结果为。否则它将为 NULL,在这种情况下,函数将评估为。'112'MIN()'Auto''112''111''Manual'IFNULL()'Other'

于 2013-01-04T10:03:39.123 回答
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;
于 2013-01-04T05:38:28.247 回答
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

只有一行将从传输连接中连接(汽车不能同时是自动和手动的),这种方法避免了所有这些子查询。

将连接设为连接意味着缺少的传输选项将显示为手册。您可以通过添加对 null 的测试来调整它以具有默认值。

于 2013-01-04T03:12:50.883 回答
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);
于 2013-01-04T02:58:10.877 回答