SQL按所有列分组


74

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

select * from table group by *

你想达到什么目的?
MarlonRibunal 2009年

50
为什么这是一个毫无意义的问题?似乎任何初学者sql程序员都可能会问。
womp

Answers:


53

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通过join,则“ distinct”为我带来2行,并在row_number()上计数两次,但是如果我正确地使用group by,只会给我一个。我正在经历!我需要一个连续的整数注册表,在x_code上“区别”数我2次。
Natan Medeiros

这错过了一些重要的情况,例如
UDAF

1
并非总是可以直接使用DISTINCT。如果查询包含ORDER BY子句,则可能会出现错误:“错误:对于SELECT DISTINCT,ORDER BY表达式必须出现在选择列表中”在这种情况下,唯一的解决方案是嵌套查询AFAIK。
祝贺

17

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

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

我们有一个简单的方法来做到这一点吗?


1
您怎么知道他想显示重复项,而不是简单地显示不同的行?
pilcrow 2012年

1
我在postgreSQL中收到GROUP BY *的语法错误
降雪

我还希望实现此用例,因为我想比较2个不同查询的结果集,包括重复项的数量。这对重构很有用
symbiont

11

如果您使用的是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

不。您是否正在尝试进行汇总?如果是这样,您可以执行以下操作以获取所需的内容

;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

4

我想对整个结果集进行计数和求和。我通过与达成了分组GROUP BY 1=1


1
我不知道它是如何工作的,但是它非常出色,正是我所需要的。此技巧是否记录在某处,并且得到所有主要关系数据库的支持?
kosmičák

3

否,因为这从根本上意味着您将不会进行任何分组。如果按所有列分组(并且具有正确定义的表且具有唯一索引),则SELECT * FROM table本质上与相同SELECT * FROM table GROUP BY *


23
当然,如果你具有唯一索引,SELECT * FROM表是一样的SELECT * FROM表GROUP BY *。在这种情况下,您可以使用SELECT DISTINCT * FROM表来完成此操作。
索伦Kuklau

7
在继承项目时,必须要处理重复的行-因此,我认为假设某人永远不想删除重复的行是不安全的。
以利亚2009年

6
还有另一种情况...从t1左联接t2上选择t1。*,count(t2.items)t1.id = t2.id GROUP BY t1。*
Danny

2

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

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


1
“开放解释”可以通过指定列的自然顺序(即定义它们的顺序)来轻松解决。通配符语法将是一个有用的功能。
StephenBoesch

-1

这是我的建议:

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  ') 

-2

您可以使用“全部分组”,但要小心,因为“全部分组”将从将来的SQL Server版本中删除。


2
“按所有人分组”与按所有列分组无关!
帕特里克·奥诺涅兹
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.