我正在尝试理解没有聚合功能的GROUP BY (oracle dbms新手)。
它是如何运作的?
这是我尝试过的。
我将运行我的SQL的EMP表
SELECT ename , sal
FROM emp
GROUP BY ename , sal
SELECT ename , sal
FROM emp
GROUP BY ename;
结果
ORA-00979:不是GROUP BY表达式
00979. 00000 - "不是GROUP BY表达式"
*原因:
*操作:
行错误:397列:16
SELECT ename , sal
FROM emp
GROUP BY sal;
结果
ORA-00979:不是GROUP BY表达式
00979. 00000 - "不是GROUP BY表达式"
*原因:
*动作:行错误:411列:8
SELECT empno , ename , sal
FROM emp
GROUP BY sal , ename;
结果
ORA-00979:不是GROUP BY表达式
00979. 00000 - "不是GROUP BY表达式"
*原因:
*动作:行错误:425列:8
SELECT empno , ename , sal
FROM emp
GROUP BY empno , ename , sal;
因此,基本上列的数量必须等于GROUP BY子句中的列数,但我仍然不明白为什么或发生了什么。
答案 0 :(得分:86)
这就是GROUP BY的工作方式。它需要几行并将它们变成一行。因此,它必须知道如何处理所有组合行,其中某些列(字段)具有不同的值。这就是为什么对于要选择的每个字段都有两个选项的原因:要么将它包含在GROUP BY子句中,要么在聚合函数中使用它,以便系统知道如何组合字段。
例如,假设你有这张表:
Name | OrderNumber
------------------
John | 1
John | 2
如果您说GROUP BY Name,它将如何知道结果中显示哪个OrderNumber?因此,您要么在group by中包含OrderNumber,这将导致这两行。或者,您使用聚合函数来显示如何处理OrderNumbers。例如,MAX(OrderNumber)
,表示结果为John | 2
或SUM(OrderNumber)
,表示结果为John | 3
。
答案 1 :(得分:23)
鉴于此数据:
Col1 Col2 Col3
A X 1
A Y 2
A Y 3
B X 0
B Y 3
B Z 1
此查询
SELECT Col1, Col2, Col3 FROM data GROUP BY Col1, Col2, Col3
会产生完全相同的表格。
但是,这个查询:
SELECT Col1, Col2 FROM data GROUP BY Col1, Col2
会导致
Col1 Col2
A X
A Y
B X
B Y
B Z
现在,查询:
SELECT Col1, Col2, Col3 FROM data GROUP BY Col1, Col2
会产生问题:带有A,Y的行是将两行分组的结果
A Y 2
A Y 3
那么,哪个值应该在Col3,'2'或'3'?
通常你会使用group by来计算,例如总和:
SELECT Col1, Col2, SUM(Col3) FROM data GROUP BY Col1, Col2
所以在我们遇到问题时,我们现在得到(2 + 3)= 5。
您在select中的所有列进行分组与使用DISTINCT实际上相同,在这种情况下最好使用DISTINCT关键字的单词可读性。
所以而不是
SELECT Col1, Col2, Col3 FROM data GROUP BY Col1, Col2, Col3
使用
SELECT DINSTINCT Col1, Col2, Col3 FROM data
答案 2 :(得分:20)
您遇到GROUP BY子句的严格要求。不在group-by子句中的每一列都必须应用一个函数来将匹配的“group”的所有记录减少到单个记录(sum,max,min等)。
如果列出GROUP BY子句中的所有查询(选定)列,则实质上是要求从结果集中排除重复记录。这与SELECT DISTINCT具有相同的效果,它也消除了结果集中的重复行。
答案 3 :(得分:7)
GROUP BY没有聚合的唯一真实用例是当GROUP BY列数超过所选列时,在这种情况下可能会重复所选列。否则你也可以使用DISTINCT。
值得注意的是,其他RDBMS不要求所有非聚合列都包含在GROUP BY中。例如,在PostgreSQL中,如果表的主键列包含在GROUP BY中,那么该表的其他列不需要保证对于每个不同的主键列都是不同的。我曾经希望Oracle在许多情况下做的与更紧凑的SQL相同。
答案 4 :(得分:4)
让我举几个例子。
考虑这些数据。
CREATE TABLE DATASET ( VAL1 CHAR ( 1 CHAR ),
VAL2 VARCHAR2 ( 10 CHAR ),
VAL3 NUMBER );
INSERT INTO
DATASET ( VAL1, VAL2, VAL3 )
VALUES
( 'b', 'b-details', 2 );
INSERT INTO
DATASET ( VAL1, VAL2, VAL3 )
VALUES
( 'a', 'a-details', 1 );
INSERT INTO
DATASET ( VAL1, VAL2, VAL3 )
VALUES
( 'c', 'c-details', 3 );
INSERT INTO
DATASET ( VAL1, VAL2, VAL3 )
VALUES
( 'a', 'dup', 4 );
INSERT INTO
DATASET ( VAL1, VAL2, VAL3 )
VALUES
( 'c', 'c-details', 5 );
COMMIT;
现在桌子上有什么
SELECT * FROM DATASET;
VAL1 VAL2 VAL3
---- ---------- ----------
b b-details 2
a a-details 1
c c-details 3
a dup 4
c c-details 5
5 rows selected.
- 按小组聚合
SELECT
VAL1,
COUNT ( * )
FROM
DATASET A
GROUP BY
VAL1;
VAL1 COUNT(*)
---- ----------
b 1
a 2
c 2
3 rows selected.
- 按多列聚合,但选择部分列
SELECT
VAL1,
COUNT ( * )
FROM
DATASET A
GROUP BY
VAL1,
VAL2;
VAL1
----
b
c
a
a
4 rows selected.
- 没有按多列聚合的小组
SELECT
VAL1,
VAL2
FROM
DATASET A
GROUP BY
VAL1,
VAL2;
VAL1
----
b b-details
c c-details
a dup
a a-details
4 rows selected.
- 没有按多列聚合的小组
SELECT
VAL1
FROM
DATASET A
GROUP BY
VAL1,
VAL2;
VAL1
----
b
c
a
a
4 rows selected.
您选择了N列(不包括聚合),那么您应该有N或N + x列
答案 5 :(得分:3)
如果SELECT子句中有一些列,如果有多行,它将如何选择它?所以是的,SELECT子句中的每一列也应该在GROUP BY子句中,你可以在SELECT ...
中使用聚合函数你可以在GROUP BY子句中使用不在SELECT子句中的列,但不能
答案 6 :(得分:2)
使用子查询,例如:
SELECT field1,field2,(SELECT distinct field3 FROM tbl2 WHERE criteria) AS field3
FROM tbl1 GROUP BY field1,field2
OR
SELECT DISTINCT field1,field2,(SELECT distinct field3 FROM tbl2 WHERE criteria) AS field3
FROM tbl1
答案 7 :(得分:1)
作为补充
基本上列数必须等于GROUP BY子句中的列数
不是正确的陈述。
答案 8 :(得分:0)
我知道你说如果你有这样的数据你想要了解分组:
COL-A COL-B COL-C COL-D
1 Ac C1 D1
2 Bd C2 D2
3 Ba C1 D3
4 Ab C1 D4
5 C C2 D5
并且您希望使数据显示为:
COL-A COL-B COL-C COL-D
4 Ab C1 D4
1 Ac C1 D1
3 Ba C1 D3
2 Bd C2 D2
5 C C2 D5
您使用:
select * from table_name
order by col-c,colb
因为我认为这是你打算做的事。