0

適切にグループ化されておらず、間違った結果を返すクエリがあり、何が問題なのかわかりません。

クエリを以下に示します。参考までに - 問題が発生する最も基本的な形式に到達するためにクエリの他の部分をすべて削除したため、現在の形式ではグループ化が必要な理由は明らかではありません。

SELECT * FROM (
  SELECT *
  FROM notifications n
  WHERE 1
  --  and group_id = '5b35c8eb075881f8bbdfbcb36b052aa7'
  GROUP BY `from`
) t 
WHERE group_id = '5b35c8eb075881f8bbdfbcb36b052aa7'

問題は、内部サブクエリ (現在はコメントアウトされています) に where を使用すると、この場合、結果が 4 つになることです。4 つの結果のそれぞれに異なる「from」値があるため、個別にリストする必要があります。サブクエリの外側に where を置くと、3 つの結果が得られます。

完全を期すために、テーブルの定義は次のとおりです。

CREATE TABLE `notifications` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`mem_id` int(10) unsigned DEFAULT NULL,
`type` varchar(255) NOT NULL,
`from` varchar(255) DEFAULT NULL,
`entry_id` int(11) DEFAULT NULL,
`parent_id` int(11) DEFAULT NULL,
`table_id` varchar(255) DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`emailed` tinyint(1) DEFAULT NULL,
`read` tinyint(1) NOT NULL,
`group_id` char(32) NOT NULL,
PRIMARY KEY (`id`),
KEY `mem_id` (`mem_id`),
KEY `created_at` (`created_at`),
KEY `entry_id` (`entry_id`),
KEY `parent_id` (`parent_id`),
KEY `group_id` (`group_id`)
)

これを引き起こす可能性のあるアイデアはありますか?私は完全に困惑しています。この時点で、それを mysql のバグに帰する準備ができていますが、それもありそうにないようです。


アップデート

「間違った結果」の意味がよくわかりませんでした。データ セットには、この group_id を持つ 7 つのレコードがありました。一意の "from" を持つ 2 つのレコードと、2 つの他の "from" ID を持つ 5 つのレコードがありました (1 つには 3 つのレコードがあり、1 つには 2 つのレコードがありました)。

グループの where を内側で実行すると、必要な 4 つのレコードが得られました。問題に直接関係がないため、例から除外した他の合計/カウントを行っているため、結果としてどの行が選択されたかは気にしません。

単一の「from」を持つ2つのレコードのうちの1つで外側のグループのwhereを実行すると、まったく返されませんでした。
私はsqlfiddleで更新しようとします(それについて知りませんでした!)-問題は、私がテストしていたこのデータベースが毎日消去されるため、元のデータがないことです。再現できるかどうかを確認します.

アップデート #2

私の質問では、内側と外側の group by について言及していることに気付きました。group by は常に内側のクエリにあり、「where」がどこにあるかだけです。フレーズを調整してみました。繰り返しになりますが、なぜ where の場所を気にするのかはすぐにはわかりませんが、私の最終的なユース ケースでは、外部で選択を行う必要があります (既読/未読の通知の数を作成しており、メンバーごととメッセージごとの合計の両方をカウントします - 例: group_id)

sqlfiddle: http://www.sqlfiddle.com/#!2/7d746/5

内部クエリのスクリーンショット: https://www.evernote.com/shard/s48/sh/e355e96e-e48d-4550-bbaf-ffb18bc0bb9c/08e2454867e00e3a05535303429748f1

外側のクエリのスクリーンショット: https://www.evernote.com/shard/s48/sh/60b10427-e417-4196-8b92-7d6d8031d21e/c779bc9c46d23472983ac6fa0d25e42d

sqlfiddle を使用すると、毎回 4 つの結果が返されます。これにより、サーバーの問題だと思います。MySQL 5.5.28-29.2 Percona Server (GPL)、Release rel29.2、Revision 360 を実行しています。

4

1 に答える 1

2

このクエリ:

  SELECT *
  FROM notifications n
  WHERE 1
  GROUP BY `from`

ANSI SQL とほとんどすべての DBMS (oracle、postgres、MS SQL など) では単純に間違っています。

非標準であるため、MySqlでのみ実行されますgroup by extension
。このリンクを参照してください:http:

//dev.mysql.com/doc/refman/5.0/en/group-by-extensions.html

ただし、これは主に、GROUP BY で指定されていない各非集計列のすべての値が各グループで同じである場合に役立ちます。サーバーは各グループから任意の値を自由に選択できるため、それらが同じでない限り、選択された値は不確定です。

この「機能」のため、クエリ (select from select * group by) は予測できず、結果はテーブル内のレコードの順序に依存します。
この簡単なデモを見てみましょう: http://www.sqlfiddle.com/#!2/b762e/2
このデモには同じ内容の 2 つの同一のテーブルがあり、唯一の違いは物理的な行の順序です。そして、同じクエリでもまったく異なる結果が得られます。



---- この問題を解決する方法を編集してください -----

クエリでこの問題を解決するには、両方の列を GROUP BY 句に追加するだけです。

select * FROM (
  SELECT * FROM notifications n
  GROUP BY `from`, `group_id`
) x
WHERE group_id = 'A';

select * FROM (
  SELECT * FROM notifications n
  WHERE group_id = 'A'
  GROUP BY `from`, `group_id`
) x

from上記の 2 つのクエリでは、列およびに対して常に同じ結果が得られますgroup_id。他の列 (GROUP BY 句に含まれていない) はランダムになる可能性があります。
簡単なデモを見てみましょう --> http://www.sqlfiddle.com/#!2/5d19b/5

于 2013-08-29T17:50:45.570 に答える