如何在 SQL 中的一个字段上选择不重复的记录?
Posted
技术标签:
【中文标题】如何在 SQL 中的一个字段上选择不重复的记录?【英文标题】:How to select records without duplicate on just one field in SQL? 【发布时间】:2012-08-27 16:16:10 【问题描述】:我有一个包含 3 列的表格,如下所示:
+------------+---------------+-------+
| Country_id | country_title | State |
+------------+---------------+-------+
这张表有很多条记录。其中一些有state
,而另一些则没有。现在,想象一下这些记录:
1 | Canada | Alberta
2 | Canada | British Columbia
3 | Canada | Manitoba
4 | China |
我需要有没有任何重复的国家名称。实际上我需要他们的id
和title
,最好的 SQL 命令是什么?我在下面的表格中使用了DISTINCT
,但我无法获得合适的结果。
SELECT DISTINCT title,id FROM tbl_countries ORDER BY title
我想要的结果是这样的:
1, Canada
4, China
【问题讨论】:
你从你尝试的查询中得到了什么结果,它与你想要的有什么不同? 我得到的结果集包含许多包含加拿大的记录。 你想做什么?你能展示你想要的结果集是什么吗?让它明确。我的意思是不要只用你自己的话来描述你想要什么。更新您的问题,以表格格式以清晰准确的方式显示您获得的准确结果和所需的准确结果。 您写“实际上我需要他们的 id 和标题”(即两列),但在您的编辑中,所需的结果只有一列。请解释这种差异。 @MarkByers 我需要防止国家名称的重复记录。我的意思是我不喜欢展示第二个加拿大,而我之前有 1 个。 【参考方案1】:DISTINCT
是关键字
对我来说,您的查询是正确的
先尝试这样做
SELECT DISTINCT title,id FROM tbl_countries
稍后您可以尝试使用 order by。
【讨论】:
查询结果只会删除State
列,这不是OP需要的;)。
这只是确保查询的每个结果元组都是唯一的,而不是列中的每个值都是唯一的。【参考方案2】:
试试这个:
SELECT MIN(id) AS id, title
FROM tbl_countries
GROUP BY title
【讨论】:
【参考方案3】:对于使用DISTINCT
关键字,你可以这样使用:
SELECT DISTINCT
(SELECT min(ti.Country_id)
FROM tbl_countries ti
WHERE t.country_title = ti.country_title) As Country_id
, country_title
FROM
tbl_countries t
使用ROW_NUMBER()
,可以这样使用:
SELECT
Country_id, country_title
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY country_title ORDER BY Country_id) As rn
FROM tbl_countries) t
WHERE rn = 1
同样使用LEFT JOIN
,你可以使用这个:
SELECT t1.Country_id, t1.country_title
FROM tbl_countries t1
LEFT OUTER JOIN
tbl_countries t2 ON t1.country_title = t2.country_title AND t1.Country_id > t2.Country_id
WHERE
t2.country_title IS NULL
使用EXISTS
,你可以试试:
SELECT t1.Country_id, t1.country_title
FROM tbl_countries t1
WHERE
NOT EXISTS (SELECT 1
FROM tbl_countries t2
WHERE t1.country_title = t2.country_title AND t1.Country_id > t2.Country_id)
【讨论】:
这个可以用来连续选择所有数据吗?正如我发现的所有示例都设置了列,当我使用 select * 运行它时它不起作用。如果这些解决方案不适用于 Select *,不确定是否要进行故障排除【参考方案4】:在 mysql 中可以使用一个特殊的列函数GROUP_CONCAT
:
SELECT GROUP_CONCAT(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'computers' AND
TABLE_NAME='Laptop' AND
COLUMN_NAME NOT IN ('code')
ORDER BY ORDINAL_POSITION;
需要说明的是,MySQL 中的信息模式涵盖了所有数据库服务器,而不是某些数据库。这就是为什么如果不同的数据库包含具有相同WHERE
子句的names, search
条件的表应该指定架构名称:TABLE_SCHEMA='computers'
。
字符串与 MySQL 中的 CONCAT
函数连接。我们问题的最终解决方案在 MySQL 中可以表示为:
SELECT CONCAT('SELECT ',
(SELECT GROUP_CONCAT(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='computers' AND
TABLE_NAME='Laptop' AND
COLUMN_NAME NOT IN ('code')
ORDER BY ORDINAL_POSITION
), ' FROM Laptop');
http://www.sql-ex.ru/help/select20.php
【讨论】:
【参考方案5】:Having
子句是在 Oracle 中查找重复条目的最简单方法,使用 rowid
我们可以删除重复数据..
DELETE FROM products WHERE rowid IN (
SELECT MAX(sl) FROM (
SELECT itemcode, (rowid) sl FROM products WHERE itemcode IN (
SELECT itemcode FROM products GROUP BY itemcode HAVING COUNT(itemcode)>1
)) GROUP BY itemcode);
【讨论】:
告诉人们在他们只想查看数据时删除他们的数据不是一个好主意。【参考方案6】:试试这个
SELECT country_id, country_title
FROM (SELECT country_id, country_title,
CASE
WHEN country_title=LAG(country_title, 1, 0) OVER(ORDER BY country_title) THEN 1
ELSE 0
END AS "Duplicates"
FROM tbl_countries)
WHERE "Duplicates"=0;
【讨论】:
【参考方案7】:忽略 SQL 中的重复行。我想这可能会对你有所帮助。
SELECT res2.*
FROM
(SELECT res1.*,ROW_NUMBER() OVER(PARTITION BY res1.title ORDER BY res1.id)as num
FROM
(select * from [dbo].[tbl_countries])as res1
)as res2
WHERE res2.num=1
【讨论】:
【参考方案8】:select Country_id,country_title from(
select Country_id,country_title,row_number() over (partition by country_title
order by Country_id ) rn from country)a
where rn=1;
【讨论】:
【参考方案9】:复杂查询可以删除重复的行,
首先将结果存储到#TempTable 或@TempTableVariable
从#TempTable 或@TempTableVariable 中删除您的条件
然后选择剩下的数据。
如果需要创建行号创建标识列。
【讨论】:
以上是关于如何在 SQL 中的一个字段上选择不重复的记录?的主要内容,如果未能解决你的问题,请参考以下文章
如何把SQL数据表中一个字段的值按逗号分隔存入另外一个表,并删除重复记录?