MySQL选择不同的多列

105

假设在MySQL数据库的一个表中有列a, b, c, d。 我想要做的是选择这4个列中所有不同的值(仅限不同的值)。我尝试了以下方法:

SELECT DISTINCT a,b,c,d FROM my_table;
SELECT DISTINCT a,b,c,d FROM my_table GROUP BY a,b,c,d;

这些都没有起作用。有人能在这里帮忙吗?

谢谢

注意 我想要分别获取列 a, b, c, d 的不同值,而不是不同组合的值。


如果有任何唯一列,这将不起作用。distinct 不适用于唯一列。 - TheTechGuy
没有任何一列是唯一的。 - user765368
@Thecrocodilehunter 当然会起作用 - 为什么在唯一列上使用distinct不起作用呢? - Adrian Cornish
4
请解释一下你所说的“这4列的所有不同值”,因为对于那些查询未返回您想要的结果,这一点对您来说必须意味着与通常情况下它的含义不同。提供样本数据和样本输出是传达这一点的简洁方式。 - Dan Grossman
2
我想要a、b、c和d的不同值,而不是值的组合。 - user765368
显示剩余2条评论
10个回答

119

我知道这个问题太老了,不过:

SELECT a, b
FROM mytable
GROUP BY a, b;

这将为您提供所有组合。


2
比较酷。'group by' 强制唯一性。这就是正在发生的事情吗? - Jibran
请问您能否详细说明一下这个查询? - Jorge Lavín
14
@ncastro 抱歉,但这个答案并没有满足问题。 - Knowledge Craving
1
对于大表格,这个速度较慢。 - John T
来了就是为了这个。我的一个查询需要近一秒钟的时间,而没有分组则只需要3ms。 - Christophe De Troyer

61

这个能有所帮助吗?

select 
(SELECT group_concat(DISTINCT a) FROM my_table) as a,
(SELECT group_concat(DISTINCT b) FROM my_table) as b,
(SELECT group_concat(DISTINCT c) FROM my_table) as c,
(SELECT group_concat(DISTINCT d) FROM my_table) as d

10
如果我只需要显示前两列的不同结果,但需要显示所有列的内容,该怎么办? - Uday Hiwarale
2
ncastro的更好。更酷,更容易,无论如何。 - Buffalo
嗨Nesim,谢谢!顺便问一下,如果"my_table"是一个完整的查询语句,我如何通过名称调用它并再次调用它? - Tomer
Chayan,那是另一个问题,但它是 REPLACE(group_concat(DISTINCT d),',',' ') - Slam
请注意,这将悄无声息地将每个结果列截断为 group_concat_max_len 个字符长,默认情况下仅为1024个字符 - 您可能会丢失数据! - thenickdude
显示剩余4条评论

27

另一种简单的方法是使用concat()函数

SELECT DISTINCT(CONCAT(a,b)) AS cc FROM my_table GROUP BY (cc);

抱歉,但我在Derby数据库中找不到任何等价物。 - Pranjal Choladhara
这很聪明,而且正是我所需要的。 - xtian
这是对我的工作有效的解决方案。我不知道如何将其他答案与我在查询中使用的多个连接一起使用。 - murume
大表格查询速度非常慢。 - John T
这个真的很聪明。 - Akmal Arzhang

22

根据你所需的结果猜测,也许这就是你想要的查询

SELECT DISTINCT a FROM my_table
UNION 
SELECT DISTINCT b FROM my_table
UNION
SELECT DISTINCT c FROM my_table
UNION
SELECT DISTINCT d FROM my_table

1
这也可行,但我更喜欢Nesim Razon答案中结果之间的分离。谢谢您。 - user765368
酷 - 我打算看看如何将它们结合起来。 - Adrian Cornish
6
如果你想要在所有列中获取唯一的值,你需要用另外一个SELECT语句包裹这个查询,像这样:SELECT DISTINCT value FROM ( SELECT DISTINCT a AS value FROM my_table UNION SELECT DISTINCT b AS value FROM my_table UNION SELECT DISTINCT c AS value FROM my_table ) AS derived - T. Brian Jones
SELECT e,f FROM ( SELECT DISTINCT zdjh AS e FROM tj_xhqdUNION SELECT DISTINCT sjsj AS f FROMtj_xhqdUNION SELECT DISTINCT xhqd AS g FROMtj_xhqd) agives me Error Code: 1054 Unknown column 'f' in 'field list' - Moeez

11

这将在所有列之间提供DISTINCT值:

SELECT DISTINCT value
FROM (
    SELECT DISTINCT a AS value FROM my_table
    UNION SELECT DISTINCT b AS value FROM my_table
    UNION SELECT DISTINCT c AS value FROM my_table
) AS derived

很好的例子,轻松解决了我的问题。谢谢。 - delliottg
2
它将给我单列中的值,如果我想分开展示它们呢? - Moeez

9

你提出的两个查询都是正确的,应该能够给你正确的答案。

我建议使用以下查询来解决你的问题。

SELECT DISTINCT a,b,c,d,count(*) Count FROM my_table GROUP BY a,b,c,d
order by count(*) desc

这是添加count(*)字段。这将让您了解使用group命令消除了多少行。


我想要a、b、c和d的不同值,而不是不同值的组合。 - user765368
@hmd:感谢您提供的解决方案,正是我需要的。有没有办法包含一个 where 条件?我只想选出计数大于1的行。尝试了 select distinct a,b,c,count(*) from MyTempTable group by a,b,c order by count(*) desc where count(*)>1; 但它没有起作用。 - Nav
@Nav42,你需要使用having count(*) > 1而不是where,因为这是聚合查询。顺便说一句,我的答案并没有完全回答上面提出的问题。无论如何,很高兴能帮助到你。 - TheTechGuy
可以运行。非常感谢。选择 distinct a,b,c,count(*) from MyTable group by a,b,c having count(*) > 1 order by count(*) desc - Nav

4

选择不同的组合(colA、colB和colC)并将它们串联在一起,从tableName表中查询结果;


1
此答案已在低质量队列中进行了审核。以下是如何撰写好的答案?的一些指南。仅有代码的答案不被认为是好的答案,并且很可能会因为对学习者社区不够有用而被投票降低或删除。这只是对您来说很明显。请解释它的作用,以及它与现有答案的不同之处/ 优点来自审核 - Trenton McKinney
不需要更多的解释,它是不言自明的。如果您不喜欢这个答案,请删除它,我之所以添加它是因为其他答案都没有那么简单。 - CWD Subs

0

根据您的答案,我编写了类似的代码,但用于提取一个名为vars的json列,其中包含8个值的数组,所有值均合并在一个列中,并修剪引号以去重。

SELECT DISTINCT TRIM(BOTH '"' FROM T1.`vars`) FROM (
    SELECT JSON_EXTRACT(`vars`, '$[1]') AS `vars` 
         FROM my_table
         WHERE `vars` != '[]'
         UNION 
    SELECT JSON_EXTRACT(`vars`, '$[2]') AS `vars`
         FROM my_table
         WHERE `vars` != '[]'
         UNION 
    SELECT JSON_EXTRACT(`vars`, '$[3]') AS `vars`
         FROM my_table
         WHERE `vars` != '[]'
         UNION 
    SELECT JSON_EXTRACT(`vars`, '$[4]') AS `vars`
         FROM my_table
         WHERE `vars` != '[]'
         UNION 
    SELECT JSON_EXTRACT(`vars`, '$[5]') AS `vars`
         FROM my_table
         WHERE `vars` != '[]'
         UNION 
    SELECT JSON_EXTRACT(`vars`, '$[6]') AS `vars`
         FROM my_table
         WHERE `vars` != '[]'
         UNION 
    SELECT JSON_EXTRACT(`vars`, '$[7]') AS `vars`
         FROM my_table
         WHERE `vars` != '[]'
         UNION 
    SELECT JSON_EXTRACT(`vars`, '$[8]') AS `vars`
         FROM my_table
         WHERE `vars` != '[]'
) T1
WHERE `vars` IS NOT NULL
AND `vars` != 'false';

希望它能有所帮助...


0

我不知道你的列值是否像我的一样是ID,所以这里是我的解决方案,如果适合你的话。

SELECT DISTINCT (sender+receiver) AS smart_sum, sender, receiver 
FROM chatTable 
WHERE sender=1 OR receiver=1 
GROUP BY smart_sum

我有一张聊天表,发送者和接收者列代表每个用户的user_id,因此它们的总和实际上是唯一的。


0

您可以使用此方法获取一个包含四个逗号分隔列表的行,其中包含所有值。

SELECT
  GROUP_CONCAT(DISTINCT `a`) AS `as`,
  GROUP_CONCAT(DISTINCT `b`) AS `bs`,                
  GROUP_CONCAT(DISTINCT `c`) AS `cs`,                
  GROUP_CONCAT(DISTINCT `d`) AS `ds`
FROM
  `my_table`;

如果您需要使用逗号以外的其他分隔符,请将SEPARATOR选项添加到GROUP_CONCAT中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接