MySQL:选择 DISTINCT / UNIQUE,但返回所有列?
SELECT DISTINCT field1, field2, field3, ......
FROM table;
我正在尝试完成以下 SQL 语句,但我希望它返回所有列。
这可能吗?
像这样的东西:
SELECT DISTINCT field1, *
FROM table;
SELECT DISTINCT field1, field2, field3, ......
FROM table;
I am trying to accomplish the following SQL statement, but I want it to return all columns.
Is this possible?
Something like this:
SELECT DISTINCT field1, *
FROM table;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(19)
您正在寻找一个 group by: ,
有时可以使用不同的 on 语句来编写:
但是,在大多数平台上,上述两种方法都不起作用,因为其他列上的行为未指定。 (第一个适用于 MySQL,如果您正在使用 MySQL。)
您可以获取不同的字段并坚持每次选择一个任意行。
在某些平台(例如 PostgreSQL、Oracle、T-SQL)上,这可以直接使用窗口函数来完成:
在其他平台(MySQL、SQLite)上,您需要编写子查询来将整个表与其自身连接起来(示例),因此不推荐。
You're looking for a group by:
Which can occasionally be written with a distinct on statement:
On most platforms, however, neither of the above will work because the behavior on the other columns is unspecified. (The first works in MySQL, if that's what you're using.)
You could fetch the distinct fields and stick to picking a single arbitrary row each time.
On some platforms (e.g. PostgreSQL, Oracle, T-SQL) this can be done directly using window functions:
On others (MySQL, SQLite), you'll need to write subqueries that will make you join the entire table with itself (example), so not recommended.
从您问题的措辞中,我了解到您希望为给定字段选择不同的值,并为每个此类值选择列出同一行中的所有其他列值。大多数 DBMS 不允许使用
DISTINCT
或GROUP BY
这样做,因为结果尚未确定。可以这样想:如果您的
field1
出现多次,则将列出field2
的值(假设您的field1
具有相同的值) code> 位于两行中,但这两行中有两个不同的field2
值)。但是,您可以使用聚合函数(明确地用于您想要显示的每个字段)并使用
GROUP BY
而不是DISTINCT
:From the phrasing of your question, I understand that you want to select the distinct values for a given field and for each such value to have all the other column values in the same row listed. Most DBMSs will not allow this with neither
DISTINCT
norGROUP BY
, because the result is not determined.Think of it like this: if your
field1
occurs more than once, what value offield2
will be listed (given that you have the same value forfield1
in two rows but two distinct values offield2
in those two rows).You can however use aggregate functions (explicitely for every field that you want to be shown) and using a
GROUP BY
instead ofDISTINCT
:如果我正确理解你的问题,它与我刚刚遇到的问题类似。您希望能够将 DISTINCT 的可用性限制到指定字段,而不是将其应用于所有数据。
如果您在没有聚合函数的情况下使用 GROUP BY,则 GROUP BY 的任何字段都将是您的 DISTINCT 字段。
如果您进行查询:
它将显示基于 field1 的单个实例的所有结果。
例如,如果您有一个包含名称、地址和城市的表。一个人有多个地址记录,但你只想要这个人的一个地址,你可以这样查询:
结果将是该名字只出现一个实例及其地址,而另一个则被省略结果表。注意:如果您的字段具有原子值,例如名字、姓氏,您希望按这两个值进行分组。
因为如果两个人具有相同的姓氏,并且您仅按姓氏进行分组,那么其中一个人将从结果中省略。你需要考虑这些事情。希望这有帮助。
If I understood your problem correctly, it's similar to one I just had. You want to be able limit the usability of DISTINCT to a specified field, rather than applying it to all the data.
If you use GROUP BY without an aggregate function, which ever field you GROUP BY will be your DISTINCT filed.
If you make your query:
It will show all your results based on a single instance of field1.
For example, if you have a table with name, address and city. A single person has multiple addresses recorded, but you just want a single address for the person, you can query as follows:
The result will be that only one instance of that name will appear with its address, and the other one will be omitted from the resulting table. Caution: if your fileds have atomic values such as firstName, lastName you want to group by both.
because if two people have the same last name and you only group by lastName, one of those persons will be omitted from the results. You need to keep those things into consideration. Hope this helps.
这是一个非常好的问题。我已经在这里阅读了一些有用的答案,但也许我可以添加更准确的解释。
只要不查询其他信息,使用 GROUP BY 语句减少查询结果的数量就很容易。假设您有下表“位置”。
现在查询
将导致:
但是,以下查询
...在 MS SQL 中引发错误,因为您的计算机如何知道您想要读取三个法国城市“里昂”、“巴黎”或“马赛”中的哪一个“法国”右侧的字段?
为了更正第二个查询,您必须添加此信息。一种方法是使用函数 MAX() 或 MIN(),在所有候选值中选择最大或最小值。 MAX() 和 MIN() 不仅适用于数值,还可以比较字符串值的字母顺序。
将导致:
或:
将导致:
只要您可以从字母(或数字)顺序的两端选择值,这些函数就是一个很好的解决方案。但如果情况并非如此呢?让我们假设您需要一个具有特定特征的值,例如以字母“M”开头。现在事情变得复杂了。
到目前为止,我能找到的唯一解决方案是将整个查询放入子查询中,并手动在其外部构造附加列:
将导致:
That's a really good question. I have read some useful answers here already, but probably I can add a more precise explanation.
Reducing the number of query results with a GROUP BY statement is easy as long as you don't query additional information. Let's assume you got the following table 'locations'.
Now the query
will result in:
However, the following query
...throws an error in MS SQL, because how could your computer know which of the three French cities "Lyon", "Paris" or "Marseille" you want to read in the field to the right of "France"?
In order to correct the second query, you must add this information. One way to do this is to use the functions MAX() or MIN(), selecting the biggest or smallest value among all candidates. MAX() and MIN() are not only applicable to numeric values, but also compare the alphabetical order of string values.
will result in:
or:
will result in:
These functions are a good solution as long as you are fine with selecting your value from the either ends of the alphabetical (or numeric) order. But what if this is not the case? Let us assume that you need a value with a certain characteristic, e.g. starting with the letter 'M'. Now things get complicated.
The only solution I could find so far is to put your whole query into a subquery, and to construct the additional column outside of it by hands:
will result in:
很好的问题@aryaxt——你可以说这是一个很好的问题,因为你5年前就问过这个问题,而我今天偶然发现了这个问题,试图找到答案!
我只是尝试编辑接受的答案以包含此内容,但万一我的编辑没有包含在内:
如果您的表不是那么大,并且假设您的主键是自动递增整数,您可以执行以下操作:
Great question @aryaxt -- you can tell it was a great question because you asked it 5 years ago and I stumbled upon it today trying to find the answer!
I just tried to edit the accepted answer to include this, but in case my edit does not make it in:
If your table was not that large, and assuming your primary key was an auto-incrementing integer you could do something like this:
尝试
Try
您可以使用
WITH
子句来完成此操作。例如:
这还允许您仅选择在
WITH
子句查询中选择的行。You can do it with a
WITH
clause.For example:
This also allows you to select only the rows selected in the
WITH
clauses query.对于SQL Server,您可以使用dense_rank 和附加窗口函数来获取指定列上具有重复值的所有行和列。这是一个示例...
这是对 col1、col2 和 col3 的每个不同组合进行行计数。
For SQL Server you can use the dense_rank and additional windowing functions to get all rows AND columns with duplicated values on specified columns. Here is an example...
This is taking a row count for each distinct combination of col1, col2, and col3.
在
ORDER BY
中,我刚刚在这里放置了示例,您也可以在其中添加 ID 字段in
ORDER BY
i have just put example here, you can also add ID field in this在其他地方找到了这个,但这是一个有效的简单解决方案:
Found this elsewhere here but this is a simple solution that works:
这样只需 1 个查询即可获得 2 个唯一列
从 '{path}' 组中选择不同的 col1,col2 by col1,col2
如果需要,您可以增加列
In this way can get 2 unique column with 1 query only
select Distinct col1,col2 from '{path}' group by col1,col2
you can increase your columns if need
将 GROUP BY 添加到要检查重复项的字段
您的查询可能看起来像
将检查 field1 以排除重复记录
,或者您可能会查询像
field1 的重复记录已从 SELECT 中排除
Add GROUP BY to field you want to check for duplicates
your query may look like
field1 will be checked to exclude duplicate records
or you may query like
duplicate records of field1 are excluded from SELECT
只需将所有字段包含在 GROUP BY 子句中即可。
Just include all of your fields in the GROUP BY clause.
可以通过内部查询来完成
It can be done by inner query
如果表中所有三列的值都是唯一的,则 SELECT DISTINCT FIELD1、FIELD2、FIELD3 FROM TABLE1 有效。
例如,如果您的名字有多个相同的值,但所选列中的姓氏和其他信息不同,则该记录将包含在结果集中。
SELECT DISTINCT FIELD1, FIELD2, FIELD3 FROM TABLE1 works if the values of all three columns are unique in the table.
If, for example, you have multiple identical values for first name, but the last name and other information in the selected columns is different, the record will be included in the result set.
如果多行中的 field1 具有相同的值,我建议使用
这种方式,所有记录都将被返回。
I would suggest using
this way if you have the same value in field1 across multiple rows, all the records will be returned.