Group by関数を使用して結果を返す方法を見つけようとしています。
GROUP BYは期待どおりに機能していますが、私の質問は次のとおりです。NULLフィールドを無視してグループ化することは可能ですか。指定されたフィールドがNULLであるすべての行が必要なため、NULLをグループ化しないようにします。
SELECT `table1`.*,
GROUP_CONCAT(id SEPARATOR ',') AS `children_ids`
FROM `table1`
WHERE (enabled = 1)
GROUP BY `ancestor`
だから今私は5行を持っていて、祖先フィールドがNULLであると言うことができます、それは私に1行を返します....しかし、私はすべて5が欲しいです。
おそらく、null列に何かを追加して、それらを一意にしてグループ化する必要がありますか? UUID()の代わりに使用する何らかのシーケンスを探していましたが、これも同様に機能する可能性があります。
SELECT `table1`.*,
IFNULL(ancestor,UUID()) as unq_ancestor
GROUP_CONCAT(id SEPARATOR ',') AS `children_ids`
FROM `table1`
WHERE (enabled = 1)
GROUP BY unq_ancestor
列Y
でグループ化すると、Y
の値がNULL
であるすべての行がグループ化されます。
この動作はSQL-2003標準で定義されています 。ただし、NULL
がNULL
と等しくないため、少し驚きです。
別の値、グループ化列のデータの一部function(数学的に言えば)でグループ化することで回避できます。
一意の列X
がある場合、これは簡単です。
X Y
-------------
1 a
2 a
3 b
4 b
5 c
6 (NULL)
7 (NULL)
8 d
SELECT GROUP_CONCAT(`X`)
FROM `tbl`
GROUP BY `Y`;
結果:
GROUP_CONCAT(`foo`)
-------------------
6,7
1,2
3,4
5
8
SELECT GROUP_CONCAT(`X`)
FROM `tbl`
GROUP BY IFNULL(`Y`, `X`);
結果:
GROUP_CONCAT(`foo`)
-------------------
6
7
1,2
3,4
5
8
SELECT GROUP_CONCAT(`X`), IFNULL(`Y`, `X`) AS `grp`
FROM `tbl`
GROUP BY `grp`;
結果:
GROUP_CONCAT(`foo`) `grp`
-----------------------------
6 6
7 7
1,2 a
3,4 b
5 c
8 d
使用できる一意の列がない場合は、代わりに一意のプレースホルダー値を生成してみてください。これは読者への演習として残しておきます。
GROUP BY IFNULL(required_field, id)
SELECT table1.*,
GROUP_CONCAT(id SEPARATOR ',') AS children_ids
FROM table1
WHERE (enabled = 1)
GROUP BY ancestor
, CASE WHEN ancestor IS NULL
THEN table1.id
ELSE 0
END
Table1に一意の識別子がある場合の以前のソリューションの高速バージョンかもしれません(table1.idとします):
SELECT `table1`.*,
GROUP_CONCAT(id SEPARATOR ',') AS `children_ids`,
IF(ISNULL(ancestor),table1.id,NULL) as `do_not_group_on_null_ancestor`
FROM `table1`
WHERE (enabled = 1)
GROUP BY `ancestor`, `do_not_group_on_null_ancestor`