汚れた溶液として...
0
の代わりにLEAST(a.id,SUBSTRING_INDEX(a.dupe_ids,',',1)+0)
の定数を置き換えるために、私の元の回答(下)のクエリが変更されました。
dupe_ids
リストから最初の値を取り出し、それを数値コンテキストで評価し、その数値をその行の数値id
と比較し、その2つのうち小さい方を返します。
SELECT COUNT(DISTINCT IF(a.dupe_ids IS NULL,a.id,LEAST(a.id,SUBSTRING_INDEX(a.dupe_ids,',',1)+0))) AS my_funky_cnt
, a.id_subscription
FROM web_manager.app a
JOIN web_manager.site s
ON s.id = a.id_site
WHERE ...
GROUP BY a.id_subscription
再びmy_funky_cnt DESC
BY ORDER、実際に式によって返されているかを見るためにGROUP BY
や集計を、削除...
SELECT a.id
, a.dupe_ids
, a.id_subscription
, IF(a.dupe_ids IS NULL,a.id,LEAST(a.id,SUBSTRING_INDEX(a.dupe_ids,',',1)+0)) AS expr
FROM web_manager.app a
JOIN web_manager.site s
ON s.id = a.id_site
WHERE ...
ORDER BY a.id_subscription, a.dupe_ids IS NULL, a.id
我々はそれを期待します戻り値:
id | dupe_ids | id_subscription | expr
2 3, 4 5343 2 -- id=2 is less than fv=3
3 2, 4 5343 2 -- fv=2 is less than id=3
4 2, 3 5343 2 -- fv=2 is less than id=4
6 7 5343 6 -- id=6 is less than fv=7
7 6 5343 6 -- fv=6 is less than id=7
1 NULL 5343 1
5 NULL 5343 5
のでGROUP BY id_subscription
とCOUNT(DISTINCT expr)
は、数値の文脈において、その最初の値を評価し、(これはテストしていない)、このアプローチは、(リストの最初の値)が最初にリスト最小のID値を有するdupes_id
に依存
の数を返しますその行の値をid
と比較します。
dupe_ids
が空の文字列、またはカンマで始まる、または最初の非空白文字が数値として解釈できない場合は、その後、expr
は0
を返すために起こっています。
EDIT
オリジナルの答えは(下記)与えられたid_subscriptionための非NULL値を持つ行のすべてを崩壊に基づいていた...質問が追加、更新された3の数を返します一緒に崩壊してはならないNULL以外の値を持つ行の例"count"の戻り値が4になりました。元の応答のクエリは3のカウントを返します。
NULL値がdupe_ids
の行の数を取得するのは簡単です。
スティッキーウィケットたちは「カンマ区切りリスト」を扱っていなかった場合、これは容易になるだろう
id dupe_ids
---- --------
2 '3,4'
3 '2,4'
4 '2,3'
6 '7'
7 '6'
... dupe_ids
列、ID値をカンマで区切ったリストの奇妙な内容です値の代わりに、別のテーブルに、行への外部キー参照があった場合。または、「重複している」行を識別するために、dupe_ids
列以外の基準がある場合。
しかし、これは質問された質問ではありませんでした。質問は、がコンマで区切られたリストを格納することを避けるほうがよいか尋ねなかった。より良いアプローチがあるかどうか。
この質問は、カンマで区切られたリストを扱っています。 (なぜカンマで区切られたリストを避けることを強く推奨するのかの例として役立ちます)。
私たちは、その後、我々はCOUNT(DISTINCT expr)
を使用することができ
id dupe_ids expr
---- -------- ------
2 '3,4' '2,3,4'
3 '2,4' '2,3,4'
4 '2,3' '2,3,4'
6 '7' '6,7'
7 '6' '6,7'
...私たちは行に同じ値を持っていたように、一緒に、id
値とともにdupe_ids
の値を持つ式を持っていた場合私たちが帰ってきた時の復帰を得る醜い部分はexpr
という値になっています。 id
を先頭に追加するか、またはdupe_ids
に追加するのは簡単ですが、結果の文字列値は同一ではありません。リストは異なる順序になります。
id
とdupe_ids
の内容に基づいて、expr
の値を返すためのMySQLには、単純な組み込み関数はありません。
ORIGINAL ANSWER
私はかかるだろうなアプローチは、式を使用し、その異なる値をカウントすることです。
dupe_ids
がnullの場合、一意の値を返します。 id
がテーブル内で一意の場合は、その列の値を使用します。 dupe_ids
がNULLでない場合は、有効なid
値ではない定数で置き換えます。 id
の値が正の整数であるとすると、0または負の値を使用します。一例として、
:私は最初のGROUP BYおよび集計せずにクエリを実行して、 "作業" された発現を確認したい
SELECT COUNT(DISTINCT IF(a.dupe_ids IS NULL,a.id,0)) AS my_funky_cnt
, a.id_subscription
FROM web_manager.app a
JOIN web_manager.site s
ON s.id = a.id_site
WHERE ...
GROUP BY a.id_subscription
ORDER BY my_funky_cnt DESC
...
SELECT a.id
, a.dupe_ids
, a.id_subscription
, IF(a.dupe_ids IS NULL,a.id,0) AS derived_col
FROM web_manager.app a
JOIN web_manager.site s
ON s.id = a.id_site
WHERE ...
ORDER BY a.id_subscription, a.dupe_ids IS NULL, a.id
我々が期待しますそれは戻ります:
id | dupe_ids | id_subscription | derived_col
1 NULL 5343 1
2 3, 4 5343 0
3 2, 4 5343 0
4 2, 3 5343 0
5 NULL 5343 5
をそうdupe_ids
null以外の同じ値を持っているとのすべての行、およびNULL dupe_ids
の行には一意の値があります。
そしてその式のCOUNT(DISTINCT
は3を返します。
あなたの質問はありますか? – Barmar
私はこの質問を「このMonty Python-esqueテーブルに対して実行するSQLステートメントとは何ですか?」という返事を返します。「...」と言いました。そして、主は言われました。「あなたは聖なるピンあなたは3つに数え、それ以上はないではない.3つはあなたの数であり、計数の数は3でなければならない。あなたは数えない。 3つの5つが出てきます – spencer7593
「AND app.dupe_ids IS NULL」を「AND app.dupe_ids IS NOT NULL」に変更してください。その後、正しいカウントを取得します。 – Barmar