4

ここでの考え方は、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)

私はこの見苦しい GROUP_CONCAT を CASE 苦境内で使用することを避けようとしていますが、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'との両方'112'が同じ行グループ内のコードの中に見つかった場合、 はMIN()を返し'Auto'、そうで'112'ない場合'111'は に評価され'Manual'ます。それ以外の場合は NULL になり、その場合、IFNULL()関数は に評価され'Other'ます。

于 2013-01-04T10:03:39.123 に答える
0

MySQLはVIEWでサブクエリをサポートしていないため、2 つの個別のVIEWSを作成する必要があります。

これを試して:

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
    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 に答える
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

送信結合から結合されるのは 1 つの行のみであり (車は自動と手動の両方にすることはできません)、このアプローチではこれらすべてのサブクエリが回避されます。

結合を結合にするということは、欠落している送信オプションがマニュアルとして表示されることを意味します。デフォルト値を持つように null のテストを追加することで、これを調整できます。

于 2013-01-04T03:12:50.883 に答える