我有一个名为content
的表内容包含content_id,android_id和user_id
content_id | android_id | user_id
a1 | b1 | c1
a1 | b2 | c2
a1 | b3 | c1
a1 | b4 | c3
a1 | b1 | c4
a2 | b2 | c1
我想为特定的content_id
选择不同的android_id和user_id的计数(如果特定的android_id出现在任何行中,即使其user_id不同,它也不应出现在任何其他行中;类似地,对于user_id,即任何所选行中的两个user_id都不应匹配)
即。对于content_id = a1,应选择以下行
a1 | b1 | c1
a1 | b2 | c2
a1 | b4 | c3
即。 b1,c1,b2,c2,b4,c3是相互不同的,并没有出现在多行中的任何一行
我想要MYSQL查询。感谢
答案 0 :(得分:1)
此查询根据给定的数据获得预期的结果:
select c1.* from
(select * from content where content_id = 'a1' group by android_id) c1
join
(select * from content where content_id = 'a1' group by user_id) c2
on
c1.android_id = c2.android_id and c1.user_id = c2.user_id;
它依赖于mysql'功能'在此问题中解释:MySQL Select rows on first occurrence of each unique value,您可以使用没有聚合器的组返回第一个不同的值。
答案 1 :(得分:1)
假设您有一个id
列来排序行,这会产生所需的结果。
SELECT COUNT(*)
FROM content AS c1
LEFT JOIN content AS c2
ON c1.content_id = c2.content_id AND c1.id > c2.id
AND (c1.android_id = c2.android_id OR c1.user_id = c2.user_id)
WHERE c1.content_id = 'a1' AND c2.id IS NULL
它基于通常的LEFT JOIN/NULL
模式来查找在另一个表中不匹配的行。在这种情况下,另一个表是同一个表,c1.id > c2.id
使它返回互斥集中表中的第一行。加入条件然后测试android_id
和user_id
;如果他们中的任何一个匹配,他们就会被排除在结果之外。
答案 2 :(得分:0)
感谢Chris Lear清理逻辑......
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(content_id INT NOT NULL
,android_id INT NOT NULL
,user_id INT NOT NULL
,PRIMARY KEY(content_id,android_id,user_id)
);
INSERT INTO my_table VALUES
(1, 1, 1),
(1, 2, 2),
(1, 3, 1),
(1, 4, 3),
(1, 1, 4),
(2, 2, 1);
SELECT x.*
FROM my_table x
LEFT
JOIN my_table y
ON y.content_id = x.content_id
AND
(
( y.user_id = x.user_id AND y.android_id < x.android_id )
OR ( y.user_id < x.user_id AND y.android_id = x.android_id )
)
WHERE y.content_id IS NULL;
+------------+------------+---------+
| content_id | android_id | user_id |
+------------+------------+---------+
| 1 | 1 | 1 |
| 1 | 2 | 2 |
| 1 | 4 | 3 |
| 2 | 2 | 1 |
+------------+------------+---------+
如果您坚持使用字母数字键,那么我建议将上面的内容转换为复合UNIQUE键,然后添加代理PK。然后你会做&#39;&lt;&#39;比较PK。
显然?,&#39;计数&#39;只是返回的行数,但如果您想要为每个content_id计数,只需将SELECT更改为SELECT content_id, COUNT(*) total
并在结尾添加GROUP BY content_id
。