2

私は物事のテーブルを持っています。単純化された構造は次のとおりです。

CREATE TABLE `things` (
  `thing_id` int(11) NOT NULL AUTO_INCREMENT,
  `thing_group` int(11) NOT NULL,
  `thing_status` int(1) NOT NULL DEFAULT '0'
);

2種類あります。プライマリーはthing_id = thing_group、一意の thing_id を持ちますが、プライマリーアイテムと同じthing_group を持ちます。

INSERT INTO `things` (`thing_id`, `thing_group`, `thing_status`) VALUES
(1, 1, 0),
(2, 1, 1),
(3, 3, 1),
(4, 3, 0),
(5, 5, 1),
(6, 5, 1),
(7, 7, 0),
(8, 7, 0),
(9, 9, 1),
(10, 9, 1),

私はこれらのペアを何千も持っています。

thing_statusthing_statusプライマリまたはセカンダリ (または両方) のいずれかで 0 にすることができますが、プライマリとセカンダリの両方で = 1を持つペアのみを (ランダムに) 選択したいと考えています。

私が提供したサンプル データから、thing_id5 と 6、または 9 と 10 のいずれかのペアのみを返す必要があります (ランダムに)

難しい部分: いくつかのものは、一次的なものだけを持つことができ、二次的なものはありません. クエリは引き続きそれらを返し、ペアになっているものと同等に扱う必要があります。

2 つのクエリを実行するのと、複雑な 1 つのクエリを実行するのとではどちらがよいでしょうか?

4

3 に答える 3

0

で行をグループ化し、行thing_group数が の合計と同じものを選択しますthing_status。結果のセットを元のテーブルに結合しthing_groupて、グループに対応する実際の行を取得します。そう:

SELECT
  t.thing_id,
  t.thing_group
FROM things t
INNER JOIN (
  SELECT thing_group
  FROM things
  GROUP BY thing_group
  HAVING COUNT(*) = SUM(thing_status)
  ORDER BY RAND()
  LIMIT 1
) g ON t.thing_group = g.thing_group
于 2012-05-02T12:36:58.070 に答える
0

私の直感では、UNION ALL. しかし... MySQL では、何が機能し、何が機能しないかが常に明確であるとは限りません。

私はこのクエリがあなたが望むことをすると信じています:

SELECT t1.thing_id, t1.group_id
FROM things t1
LEFT JOIN things t2
    ON t2.thing_id = t2.thing_group
    AND t1.thing_id != t2.thing_id
WHERE (
    t1.thing_id = t1.thing_group
    AND t2.thing_id IS NULL
) OR (
    t1.thing_group = t2.thing_id
    AND t1.thing_id != t1.thing_group
)
GROUP BY t1.thing_id, t1.group_id
于 2012-05-02T04:17:21.273 に答える
0

それほど難しいことではありませんが、おそらくランダムな部分はもう少しトリッキーです:

select * 
from things 
where 
  thing_group = (select thing_group
                 from things 
                 where thing_status = 1 
                 group by thing_group
                 having count(thing_id) = 2
                 limit 1)
limit 1
于 2012-05-02T12:38:07.083 に答える