MYSQL在多行中相互不同的列

时间:2017-05-25 08:18:48

标签: mysql sql database mysqli

我有一个名为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查询。感谢

3 个答案:

答案 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_iduser_id;如果他们中的任何一个匹配,他们就会被排除在结果之外。

DEMO

答案 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