3

孤立しているか、ペアになっているレコードのテーブルがあります。各アイテムにはステータスが関連付けられています。テーブルからランダムに孤立したレコードまたはペアになったレコードを選択する必要があります (ペアの場合は両方のレコード) が、どちらかのステータスが 0 のペアは選択しません。

次の表があります。

    Table: things
+------------+---------++---------+
| id         | cluster | status   |
+------------+---------++---------+
| 1          |  1      | 0        |
| 2          |  1      | 1        |
| 3          |  3      | 1        |
| 4          |  4      | 1        |
| 5          |  4      | 0        |
| 6          |  6      | 1        |
| 7          |  6      | 1        |
| 8          |  8      | 1        |
+------------+---------++---------+

私のクエリ

SELECT 
things.id as clusterid, 
things.id as id1, 
things2.id as id2,   
(SELECT count(id) FROM things WHERE cluster= clusterid) as num_nodes
FROM things
LEFT JOIN things AS things2 ON (
    things2.status= 1  
    AND things2.cluster= things.cluster
    AND things2.id!= things.cluster)
WHERE things.status= 1 
AND things.id= things.cluster
ORDER BY RAND() LIMIT 1

このクエリは、次のレコードの組み合わせのいずれかをランダムに返します (リスト ID)。

3
6 and 7
8

私のクエリはこれを行いますが、 も返しますid 4。これは、num_nodes が 2 を返すため、ここにあるべきではありませんが、クラスター内の 2 番目のもののステータスが 0 ( id 5) であるため、このペアは無視する必要があります。

num_nodes 出力を使用して、純粋な mysql でこれらのペアを適切に削除する方法がわかりません。

結果が結合された単一の行ではなく、テーブルからの 2 つの別個の行になる場合は、ボーナス ポイント。したがって、孤立したレコードの場合status = 1、結果は 1 行になります。両方がstatus = 12行のペアレコードの場合。

4

2 に答える 2

1

これにより、サブクエリの制限なしの制限が回避されます。Eggyal の元の回答を微調整します。

  SELECT * FROM things AS t WHERE cluster IN (
    SELECT * FROM (
      SELECT things.cluster 
        FROM
                    things
          LEFT JOIN things AS things2 ON (
                things2.cluster = things.cluster
            AND things2.id     != things.cluster
          )
        WHERE
              things.status = 1
          AND (things2.id IS NULL OR things2.status = 1)
          AND things.id = things.cluster
        ORDER BY RAND()
        LIMIT 1
    ) as cheese
  )
于 2012-05-02T14:21:15.170 に答える
0

クラスタの 2 番目のステータスが 0 の場合でも許可する必要がありLEFT JOINます。次に、両方のステータスが 1 のレコードまたは 2 番目のステータスがないレコードをテストします。

SELECT 
  things.id  AS clusterid, 
  things.id  AS id1, 
  things2.id AS id2,   
  (SELECT count(id) FROM things WHERE cluster = clusterid) AS num_nodes
    -- num_nodes could instead be defined as: IF(things2.id IS NULL, 1, 2)
FROM
            things
  LEFT JOIN things AS things2 ON (
        things2.cluster = things.cluster
    AND things2.id     != things.cluster
  )
WHERE
      things.status = 1
  AND (things2.id IS NULL OR things2.status = 1)
  AND things.id = things.cluster
ORDER BY RAND()
LIMIT 1

ものごとに別々の行を返すには:

SELECT * FROM things AS t WHERE cluster IN (
  SELECT things.cluster 
    FROM
                things
      LEFT JOIN things AS things2 ON (
            things2.cluster = things.cluster
        AND things2.id     != things.cluster
      )
    WHERE
          things.status = 1
      AND (things2.id IS NULL OR things2.status = 1)
      AND things.id = things.cluster
    ORDER BY RAND()
    LIMIT 1
)
于 2012-05-02T13:34:51.743 に答える