【问题标题】:How to select records without duplicate on just one field in SQL?如何在 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   |

我需要有没有任何重复的国家名称。实际上我需要他们的idtitle,最好的 SQL 命令是什么?我在下面的表格中使用了DISTINCT,但我无法获得合适的结果。

SELECT DISTINCT title,id FROM tbl_countries ORDER BY title

我想要的结果是这样的:

1, Canada  
4, China

【问题讨论】:

  • 你从你尝试的查询中得到了什么结果,它与你想要的有什么不同?
  • 我得到的结果集包含许多包含加拿大的记录。
  • 你想做什么?你能展示你想要的结果集是什么吗?让它明确。我的意思是不要只用你自己的话来描述你想要什么。更新您的问题,以表格格式以清晰准确的方式显示您获得的准确结果和所需的准确结果。
  • 您写“实际上我需要他们的 id 和标题”(即两列),但在您的编辑中,所需的结果只有一列。请解释这种差异。
  • @MarkByers 我需要防止国家名称的重复记录。我的意思是我不喜欢展示第二个加拿大,而我之前有 1 个。

标签: sql select duplicates distinct


【解决方案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 中删除您的条件

            然后选择剩下的数据。

            如果需要创建行号创建标识列。

            【讨论】:

              猜你喜欢
              • 2018-12-03
              • 2017-01-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-17
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多