【问题标题】:SQL grouping by all the columnsSQL 按所有列分组
【发布时间】:2010-10-22 12:04:09
【问题描述】:

有没有办法在不指定列名的情况下按表的所有列分组?喜欢:

select * from table group by *

【问题讨论】:

  • 你想完成什么?
  • 为什么这是一个毫无意义的问题?似乎任何初学者 sql 程序员都可能会问。
  • 在查询 select count(distinct *) from blah 时不计算空值行的配置单元表时,这将很有用

标签: sql


【解决方案1】:

DISTINCT 关键字


我相信你想要做的是:
SELECT DISTINCT * FROM MyFooTable;

如果您按所有列分组,您只是要求删除重复数据。

例如具有以下数据的表:

 id |     value      
----+----------------
  1 | foo
  2 | bar
  1 | foo
  3 | something else

如果您执行以下与SELECT * FROM MyFooTable GROUP BY * 基本相同的查询,如果您假设 * 表示所有列:

SELECT * FROM MyFooTable GROUP BY id, value;

 id |     value      
----+----------------
  1 | foo
  3 | something else
  2 | bar

它会删除所有重复值,这在语义上与使用 DISTINCT 关键字基本相同,但结果的排序除外。例如:

SELECT DISTINCT * FROM MyFooTable;

 id |     value      
----+----------------
  1 | foo
  2 | bar
  3 | something else

【讨论】:

  • 我认为这是不正确的。如果在某些东西上使用 row_number(),则不同的计数更多。如果我有一个 x_code,其中有两个 y_code 通过连接,“distinct”会给我带来 2 行并在 row_number() 上计数两次,但如果我正确使用 group by 只会给我带来一个。我正在经历它!我需要一个顺序整数注册表,并且在 x_code 上“不同”计数我 2 次。
  • 这遗漏了几个重要的案例比如UDAF的
  • 并不总是可以直接使用 DISTINCT。如果查询包含 ORDER BY 子句,则可能会收到错误:“错误:对于 SELECT DISTINCT,ORDER BY 表达式必须出现在选择列表中”这种情况下唯一的解决方案是嵌套查询 AFAIK。
【解决方案2】:

他正在尝试查找并显示表格中的重复行。

SELECT *, COUNT(*) AS NoOfOccurrences
FROM TableName GROUP BY *
HAVING COUNT(*) > 1

我们有一个简单的方法来完成这个吗?

【讨论】:

  • 你怎么知道他想显示重复,而不是简单地显示不同的行?
  • 我在 postgreSQL 中遇到 GROUP BY * 的语法错误
  • 我也在寻求实现这个用例,因为我想比较来自 2 个不同查询的结果集,包括重复的数量。这对于重构很有用
  • 这应该是评论,而不是答案
【解决方案3】:

如果您使用的是 SqlServer,则 distinct 关键字应该适合您。 (不确定其他数据库)

declare @t table (a int , b int)

insert into @t (a,b) select 1, 1
insert into @t (a,b) select 1, 2
insert into @t (a,b) select 1, 1

select distinct * from @t

结果

a b
1 1
1 2

【讨论】:

    【解决方案4】:

    我想对整个结果集进行计数和求和。我用GROUP BY 1=1实现了所有人的分组。

    【讨论】:

    • 我不知道它是如何工作的,但它非常棒,正是我所需要的。这个技巧是否记录在某个地方并且所有主要的关系数据库都支持它?
    【解决方案5】:

    不。你想进行一些聚合吗?如果是这样,你可以做这样的事情来得到你需要的东西

    ;with a as
    (
         select sum(IntField) as Total
         from Table
         group by CharField
    )
    select *, a.Total
    from Table t
    inner join a
    on t.Field=a.Field
    

    【讨论】:

      【解决方案6】:

      简短的回答:不。 GROUP BY 子句本质上要求它们排列结果的方式。不同的字段分组顺序会导致不同的结果。

      指定通配符会使语句易于解释和不可预测的行为。

      【讨论】:

      • "开放解释" 这很容易通过指定列的自然顺序来解决 - 即它们被定义的顺序。通配符语法将是一个有用的功能。
      • 作为一个隐式约定,它仍然是不可预测的,并且取决于select 子句中指定的顺序。作为一个功能可能有意义,但不确定它是否与 SQL 理论模型兼容。
      【解决方案7】:

      不,因为这从根本上意味着您不会对任何内容进行分组。如果您按所有列分组(并且有一个正确定义的带有唯一索引的表),那么SELECT * FROM tableSELECT * FROM table GROUP BY * 本质上是一样的。

      【讨论】:

      • 当然,如果你没有有唯一索引,SE​​LECT * FROM table not和SELECT * FROM table GROUP BY一样*。在这种情况下,您可以使用 SELECT DISTINCT * FROM table 来完成此操作。
      • 在继承项目时,重复行是您必须处理的常见问题 - 所以我认为假设某人永远不想删除重复行是不安全的。
      • 还有一种情况... SELECT t1.*,count(t2.items) FROM t1 LEFT JOIN t2 ON t1.id = t2.id GROUP BY t1.*
      【解决方案8】:

      这是我的建议:

      DECLARE @FIELDS VARCHAR(MAX), @NUM INT
      
      --DROP TABLE #FIELD_LIST
      
      SET @NUM = 1
      SET @FIELDS = ''
      
      SELECT 
      'SEQ' = IDENTITY(int,1,1) ,
      COLUMN_NAME
      INTO #FIELD_LIST
      FROM Req.INFORMATION_SCHEMA.COLUMNS
      WHERE TABLE_NAME = N'new340B'
      
      WHILE @NUM <= (SELECT COUNT(*) FROM #FIELD_LIST)
      BEGIN
      SET @FIELDS = @FIELDS + ',' + (SELECT COLUMN_NAME FROM #FIELD_LIST WHERE SEQ = @NUM)
      SET @NUM = @NUM + 1
      END
      
      SET @FIELDS = RIGHT(@FIELDS,LEN(@FIELDS)-1)
      
      EXEC('SELECT ' + @FIELDS + ', COUNT(*) AS QTY FROM [Req].[dbo].[new340B] GROUP BY ' + @FIELDS + ' HAVING COUNT(*) > 1  ') 
      

      【讨论】:

        【解决方案9】:

        您可以使用 Group by All,但要小心,因为 Group by All 将从 SQL Server 的未来版本中删除。

        【讨论】:

        • ´Group by All´ 与按所有列分组无关!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多