首页 文章

SQL / mysql - 选择distinct / UNIQUE但返回所有列?

提问于
浏览
309
SELECT DISTINCT field1, field2, field3, ......   FROM table

我试图完成以下sql语句,但我希望它返回所有列是否可能?就像是:

SELECT DISTINCT field1, * from table

15 回答

  • 342

    您正在寻找一个小组:

    select *
    from table
    group by field1
    

    偶尔可以使用不同的语句编写:

    select distinct on field1 *
    from table
    

    但是,在大多数平台上,上述两种方法都不起作用,因为未指定其他列上的行为 . (第一个在MySQL中工作,如果你正在使用它 . )

    您可以获取不同的字段并坚持每次选择一个任意行 .

    在某些平台上(例如PostgreSQL,Oracle,T-SQL),可以使用窗口函数直接完成:

    select *
    from (
       select *,
              row_number() over (partition by field1 order by field2) as row_number
       from table
       ) as rows
    where row_number = 1
    

    在其他人(MySQL,SQLite)上,你需要编写子查询来使你自己加入整个表(example),所以不推荐 .

  • 3

    根据您的问题的措辞,我理解您要为给定字段选择不同的值,并为每个这样的值选择列出的同一行中的所有其他列值 . 大多数DBMS都不允许使用 DISTINCTGROUP BY ,因为结果未确定 .

    可以这样想:如果您的 field1 多次出现,将列出 field2 的值(假设您在两行中具有相同的 field1 值,但在这两行中有两个不同的 field2 值) .

    但是,您可以使用聚合函数(对于您希望显示的每个字段显式)并使用 GROUP BY 而不是 DISTINCT

    SELECT field1, MAX(field2), COUNT(field3), SUM(field4), .... FROM table GROUP BY field1
    
  • 18

    如果我正确理解你的问题,它就像我刚才那样 . 您希望能够将DISTINCT的可用性限制为指定字段,而不是将其应用于所有数据 .

    如果你使用没有聚合函数的GROUP BY,那么GROUP BY将成为你的DISTINCT字段 .

    如果您提出以下问题:

    SELECT * from table GROUP BY field1;
    

    它将根据field1的单个实例显示所有结果 .

    例如,如果您有一个包含姓名,地址和城市的表格 . 一个人记录了多个地址,但您只需要一个人的单个地址,您可以查询如下:

    SELECT * FROM persons GROUP BY name;
    

    结果将只显示该名称的一个实例及其地址,另一个将从结果表中省略 . 警告:如果您的文件具有原子值,例如firstName,则需要将lastName分组 .

    SELECT * FROM persons GROUP BY lastName, firstName;
    

    因为如果两个人具有相同的姓氏,并且您只按lastName分组,则会从结果中省略其中一个人 . 你需要考虑这些事情 . 希望这可以帮助 .

  • -3
    SELECT  c2.field1 ,
            field2
    FROM    (SELECT DISTINCT
                    field1
             FROM   dbo.TABLE AS C
            ) AS c1
            JOIN dbo.TABLE AS c2 ON c1.field1 = c2.field1
    
  • 11

    这是一个非常好的问题 . 我已经在这里阅读了一些有用的答案,但我可能会添加一个更精确的解释 .

    只要不查询其他信息,使用GROUP BY语句减少查询结果的数量就很容易 . 我们假设你有下表“位置” .

    --country-- --city--
     France      Lyon
     Poland      Krakow
     France      Paris
     France      Marseille
     Italy       Milano
    

    现在查询

    SELECT country FROM locations
    GROUP BY country
    

    将导致:

    --country--
     France
     Poland
     Italy
    

    但是,以下查询

    SELECT country, city FROM locations
    GROUP BY country
    

    ...在MS SQL中抛出一个错误,因为你的计算机怎么能知道你想在“法国”右边的字段中读到的三个法国城市“Lyon”,“Paris”或“Marseille”中的哪一个?

    要更正第二个查询,您必须添加此信息 . 一种方法是使用函数MAX()或MIN(),选择所有候选中的最大值或最小值 . MAX()和MIN()不仅适用于数值,还可以比较字符串值的字母顺序 .

    SELECT country, MAX(city) FROM locations
    GROUP BY country
    

    将导致:

    --country-- --city--
     France      Paris
     Poland      Krakow
     Italy       Milano
    

    要么:

    SELECT country, MIN(city) FROM locations
    GROUP BY country
    

    将导致:

    --country-- --city--
     France      Lyon
     Poland      Krakow
     Italy       Milano
    

    只要您可以从字母(或数字)顺序的两端选择值,这些函数就是一个很好的解决方案 . 但如果不是这样呢?我们假设你需要一个具有某种特征的值,例如以字母'M'开头 . 现在事情变得复杂了 .

    到目前为止,我能找到的唯一解决方案是将整个查询放入子查询中,并手动构建其他列:

    SELECT
         countrylist.*,
         (SELECT TOP 1 city
         FROM locations
         WHERE
              country = countrylist.country
              AND city like 'M%'
         )
    FROM
    (SELECT country FROM locations
    GROUP BY country) countrylist
    

    将导致:

    --country-- --city--
     France      Marseille
     Poland      NULL
     Italy       Milano
    
  • -2

    很棒的问题@aryaxt - 你可以说这是一个很好的问题,因为5年前我问过它,今天偶然发现它试图找到答案!

    我只是尝试编辑接受的答案以包含此内容,但万一我的编辑没有进入:

    如果你的表不是那么大,并假设你的主键是一个自动递增的整数,你可以做这样的事情:

    SELECT 
      table.*
    FROM table
    --be able to take out dupes later
    LEFT JOIN (
      SELECT field, MAX(id) as id
      FROM table
      GROUP BY field
    ) as noDupes on noDupes.id = table.id
    WHERE
      //this will result in only the last instance being seen
      noDupes.id is not NULL
    
  • 48

    你可以使用 WITH 子句来完成它 .

    例如:

    WITH c AS (SELECT DISTINCT a, b, c FROM tableName)
    SELECT * FROM tableName r, c WHERE c.rowid=r.rowid AND c.a=r.a AND c.b=r.b AND c.c=r.c
    

    这也允许您仅选择 WITH 子句查询中选择的行 .

  • -1

    对于SQL Server,您可以使用dense_rank和其他窗口函数来获取指定列上具有重复值的所有行和列 . 这是一个例子......

    with t as (
        select col1 = 'a', col2 = 'b', col3 = 'c', other = 'r1' union all
        select col1 = 'c', col2 = 'b', col3 = 'a', other = 'r2' union all
        select col1 = 'a', col2 = 'b', col3 = 'c', other = 'r3' union all
        select col1 = 'a', col2 = 'b', col3 = 'c', other = 'r4' union all
        select col1 = 'c', col2 = 'b', col3 = 'a', other = 'r5' union all
        select col1 = 'a', col2 = 'a', col3 = 'a', other = 'r6'
    ), tdr as (
        select 
            *, 
            total_dr_rows = count(*) over(partition by dr)
        from (
            select 
                *, 
                dr = dense_rank() over(order by col1, col2, col3),
                dr_rn = row_number() over(partition by col1, col2, col3 order by other)
            from 
                t
        ) x
    )
    
    select * from tdr where total_dr_rows > 1
    

    这是对col1,col2和的每个不同组合进行行计数COL3 .

  • -2
    SELECT *
    FROM tblname
    GROUP BY duplicate_values
    ORDER BY ex.VISITED_ON DESC
    LIMIT 0 , 30
    

    ORDER BY 我刚刚在这里放了例子,你也可以在这里添加ID字段

  • 1

    将GROUP BY添加到要检查查询可能类似的重复项的字段中

    SELECT field1, field2, field3, ......   FROM table GROUP BY field1
    

    将检查field1以排除重复记录

    或者您可以查询

    SELECT *  FROM table GROUP BY field1
    

    从SELECT中排除field1的重复记录

  • -1

    我建议使用

    SELECT  * from table where field1 in 
    (
      select distinct field1 from table
    )
    

    这样,如果跨越多行在field1中具有相同的值,则将返回所有记录 .

  • 0

    只需在GROUP BY子句中包含所有字段即可 .

  • 2

    它可以通过内部查询来完成

    $query = "SELECT * 
                FROM (SELECT field
                    FROM table
                    ORDER BY id DESC) as rows               
                GROUP BY field";
    
  • 5
    SELECT * from table where field in (SELECT distinct field from table)
    
  • -3

    如果表中所有三列的值都是唯一的,则SELECT DISTINCT FIELD1,FIELD2,FIELD3 FROM TABLE1有效 .

    例如,如果您的名字有多个相同的值,但所选列中的姓氏和其他信息不同,则记录将包含在结果集中 .

相关问题