web-dev-qa-db-ja.com

複数の "GROUP_CONCAT"とWHERE句

テーブルとして

id    name      type           info
1     BMW       car            yes
2     Reno      car            no
3     IBM       electronics    no
4     Sony      electronics    yes
5     Mazda     car            yes

私が使う GROUP_CONCATを使用して各typeのリストを取得しますが、連結された列をinfo列で分類された複数の列に分離したいと思います。それは次のようなものでなければなりません

SELECT type,
       GROUP_CONCAT(name) ORDER BY id ASC SEPARATOR ' ') AS list_with_info
       GROUP_CONCAT(name) ORDER BY id ASC SEPARATOR ' ') AS list_without_info
       FROM table1 GROUP BY type

WHERE句を導入したり、他のアプローチを使用して複数の連結列を返すにはどうすればよいですか?

5
Googlebot
SELECT type,
       GROUP_CONCAT( CASE WHEN info = 'yes' THEN name ELSE NULL END 
                     ORDER BY id ASC SEPARATOR ' ') AS list_with_info,
       GROUP_CONCAT( CASE WHEN info = 'no' THEN name ELSE NULL END 
                     ORDER BY id ASC SEPARATOR ' ') AS list_without_info      
FROM table1
GROUP BY type ;

SQL-Fiddleでテスト:test-1


結果を1行ではなく2行で表示したい場合は、GROUP BY両方type, infoのほうが簡単です。

SELECT 
    type, info,
    GROUP_CONCAT( name ORDER BY id ASC SEPARATOR ' ')
      AS list     
FROM table1
GROUP BY type
       , info ;

これは、必要なタイプごとに1行のフォーマットを提供するためにも使用できます。

SELECT
    type,
    MIN( CASE WHEN info = 'yes' THEN list END )
      AS list_with_info,
    MIN( CASE WHEN info = 'no' THEN list END )
      AS list_without_info    
FROM
    ( SELECT 
          type, info,
          GROUP_CONCAT( name ORDER BY id ASC SEPARATOR ' ')
            AS list     
      FROM table1
      GROUP BY type
             , info 
    ) AS grp 
GROUP BY type ;

SQL-Fiddleでテスト:test-2

上記の2つのクエリは、(type, info, name)のインデックスからメリットを得られます


以下は(info, type, name)のインデックスから利益を得るでしょう:

SELECT
    dt.type,
    grpy.list  AS list_with_info,
    grpn.list  AS list_without_info    
FROM
    ( SELECT DISTINCT type
      FROM table1
    ) AS dt
  LEFT JOIN
    ( SELECT 
          type,
          GROUP_CONCAT( name ORDER BY id ASC SEPARATOR ' ')
            AS list     
      FROM table1
      WHERE info = 'yes'
      GROUP BY type 
    ) AS grpy
      ON grpy.type = dt.type
  LEFT JOIN
    ( SELECT 
          type,
          GROUP_CONCAT( name ORDER BY id ASC SEPARATOR ' ')
            AS list     
      FROM table1
      WHERE info = 'no'
      GROUP BY type 
    ) AS grpn
      ON grpn.type = dt.type ;

SQL-Fiddleでテスト:test-

11
ypercubeᵀᴹ