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和次要的,它将具有一个 unqiue 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_status对于主要或次要(或两者)可以为 0,但我只想(随机)选择一对(随机)thing_status对于主要和次要事物都有 = 1。

所以从我提供的样本数据来看,它应该只返回thing_id5 和 6 或 9 和 10 对(随机)

困难的部分:有些东西可以只有主要的东西,没有次要的东西。查询仍应返回这些并将它们平等地对待成对出现的事物。

我最好做 2 个查询还是一个复杂的单个查询?

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

我的直觉说你应该使用 2 个查询和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 回答