我有一张桌子。这是一个简化的结构:
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'
);
有两种类型的东西。主要的,有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_id
5和6,或9和10(随机)的对
困难部分: 有些东西只能有主要的东西,没有次要的东西。查询应该仍然返回那些并将它们平等地对待成对的事物。
我最好做2次查询或复杂的单一查询吗?
答案 0 :(得分:0)
我的直觉说你应该使用UNION ALL
的2个查询。但是......使用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
答案 1 :(得分: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
答案 2 :(得分: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