2

この簡略版に似たテーブルがあります。

CREATE TABLE `accounts` (
  `id` int(11) NOT NULL,
  `account_type_id` int(10) NOT NULL,
  `type` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `accounts` VALUES (1,1,'single'),(2,1,'single'),(3,1,'single'),(4,1,'single'),(5,1,'single'),(6,1,'single'),(7,1,'single'),(8,1,'single'),(9,1,'single'),(10,2,'single'),(11,2,'single'),(12,2,'single'),(13,2,'single'),(14,2,'single'),(15,2,'single'),(16,2,'single'),(17,2,'single'),(18,2,'single'),(19,2,'single'),(20,2,'single'),(21,1,'joint'),(22,1,'joint'),(23,1,'joint'),(24,1,'joint'),(25,1,'joint'),(26,1,'joint'),(27,1,'joint'),(28,1,'joint'),(29,1,'joint'),(30,1,'joint'),(31,2,'joint'),(32,2,'joint'),(33,2,'joint'),(34,2,'joint'),(35,2,'joint'),(36,2,'joint'),(37,2,'joint'),(38,2,'joint'),(39,2,'joint'),(40,2,'joint'),(41,3,'single'),(42,3,'single'),(43,3,'single'),(44,3,'single'),(45,3,'single'),(46,3,'single'),(47,3,'single'),(48,3,'single'),(49,3,'single'),(50,3,'single'),(51,3,'single'),(52,3,'single'),(53,3,'single'),(54,3,'single'),(55,3,'single'),(56,3,'single'),(57,3,'single'),(58,3,'single'),(59,3,'single'),(60,3,'single'),(61,3,'joint'),(62,3,'joint'),(63,3,'joint'),(64,3,'joint'),(65,3,'joint'),(66,3,'joint'),(67,3,'joint'),(68,3,'joint'),(69,3,'joint'),(70,3,'joint'),(71,3,'joint'),(72,3,'joint'),(73,3,'joint'),(74,3,'joint'),(75,3,'joint'),(76,3,'joint'),(77,3,'joint'),(78,3,'joint'),(79,3,'joint'),(80,3,'joint');

維持したい:

  • ランダム 5x タイプ = シングル、account_type_id = 1 または 2
  • ランダム 5x タイプ = ジョイント、account_type_id = 1 または 2
  • ランダム 5x タイプ = シングル、account_type_id = 3
  • ランダム 5x タイプ = ジョイント、account_type_id = 3

私のアプローチは、上記のそれぞれに一致する 5 つのレコードの ID を取得してから、他のすべてを削除することでした。

(SELECT id FROM accounts WHERE account_type_id IN (1, 2) AND `type` = 'single' ORDER BY RAND() LIMIT 5)
  UNION
(SELECT id FROM accounts WHERE account_type_id IN (1, 2) AND `type` = 'joint' ORDER BY RAND() LIMIT 5)
  UNION
(SELECT id FROM accounts WHERE account_type_id = 3 AND `type` = 'single' ORDER BY RAND() LIMIT 5)
  UNION
(SELECT id FROM accounts WHERE account_type_id = 3 AND `type` = 'joint' ORDER BY RAND() LIMIT 5)

これは、必要なタイプごとに 5 つの ID を正しく返します。ただし、その結果セットを直接使用しようとすると、エラーが発生します (例でWHERE id NOT IN (...)は に置き換えました)。DELETESELECT

SELECT * FROM accounts WHERE id NOT IN(
    (SELECT id FROM accounts WHERE account_type_id IN (1, 2) AND `type` = 'single' ORDER BY RAND() LIMIT 5)
      UNION
    (SELECT id FROM accounts WHERE account_type_id IN (1, 2) AND `type` = 'joint' ORDER BY RAND() LIMIT 5)
      UNION
    (SELECT id FROM accounts WHERE account_type_id = 3 AND `type` = 'single' ORDER BY RAND() LIMIT 5)
      UNION
    (SELECT id FROM accounts WHERE account_type_id = 3 AND `type` = 'joint' ORDER BY RAND() LIMIT 5)
);

Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION   (SELECT id FROM accounts WHERE account_type_id IN (1, 2) AND `type` = 'j' at line 3

次に、次のように中間サブクエリを追加すると:

SELECT * FROM accounts WHERE id NOT IN(
    SELECT a.id FROM (
        (SELECT id FROM accounts WHERE account_type_id IN (1, 2) AND `type` = 'single' ORDER BY RAND() LIMIT 5)
          UNION
        (SELECT id FROM accounts WHERE account_type_id IN (1, 2) AND `type` = 'joint' ORDER BY RAND() LIMIT 5)
          UNION
        (SELECT id FROM accounts WHERE account_type_id = 3 AND `type` = 'single' ORDER BY RAND() LIMIT 5)
          UNION
        (SELECT id FROM accounts WHERE account_type_id = 3 AND `type` = 'joint' ORDER BY RAND() LIMIT 5)
    ) a
);

必要な結果が得られました...追加のクエリが必要な理由を誰か説明してください。

4

1 に答える 1

0

NOT IN と言う場合

ID がフィールド セットにありません (1 ,2,3,4,5 ,...)

クエリで NOT IN を検索すると、ユニオン クエリが見つかります。値のセットはありません。

ただし、a.idを選択する追加のサブクエリを作成すると、すでにidの値が設定されています

次に、NOT IN(それらのID)と言うと、正しい結果が返されます。

あなたは私が何を意味するかを知っています。

于 2013-10-01T18:12:36.143 に答える