根据从子查询返回的行计数从mysql返回不同的数据

时间:2012-05-02 13:15:51

标签: mysql

我有一张记录表,无论是孤儿还是成对出现。每个项目都有一个与之关联的状态。我需要从表中选择一个随机的孤立或配对记录(两个记录都是一对),但不是任何一个状态为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

此查询应随机返回以下任意记录组合(列出ids):

3
6 and 7
8

我的查询执行此操作,但它也返回id 4,由于num_nodes将返回2,因此不应该在此处,但由于群集中第二件事的状态为0({{1} }},这一对应该被忽视。

我不知道如何使用num_nodes输出来正确地消除纯mysql中的这些对。

如果结果可以是表中的2个单独的行,而不是连接的单行,则获得奖励积分。因此,如果孤立记录为id 5,则结果为1行。如果它是两个具有status = 1,2行的事物的配对记录。

2 个答案:

答案 0 :(得分:1)

这绕过子查询限制中的无LIMIT。稍微调整了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
  )

答案 1 :(得分:0)

即使集群中的第二件事具有0状态,您也需要允许LEFT JOIN,然后测试具有状态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
    -- 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
)