每个 GROUP BY 表达式必须至少包含一列不是外部引用

问题描述 投票:0回答:9

我在这里做错了什么?我收到此错误:

SELECT LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), 
            PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', 
            batchinfo.datapath), 8000))-1),
            qvalues.name,
            qvalues.compound,
            qvalues.rid
FROM batchinfo JOIN qvalues ON batchinfo.rowid=qvalues.rowid
WHERE LEN(datapath)>4
GROUP BY 1,2,3
HAVING rid!=MAX(rid)

我想按具有最大rid 的第一、第二和第三列进行分组。

无需 group by 和having 即可正常工作。

sql-server t-sql
9个回答
32
投票

首先你不能这样做:

having rid!=MAX(rid)

HAVING 子句只能包含聚合组的属性。

此外,

1, 2, 3
在 SQL Server 中的 GROUP BY 中无效 - 我认为这仅在 ORDER BY 中有效。

你能解释一下为什么这不是你要找的吗:

select 
LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1),
qvalues.name,
qvalues.compound,
MAX(qvalues.rid)
 from batchinfo join qvalues on batchinfo.rowid=qvalues.rowid
where LEN(datapath)>4
group by LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1),
qvalues.name,
qvalues.compound

25
投票

嗯,正如之前所说,你不能通过文字来

GROUP
,我认为你很困惑,因为你可以通过1、2、3来
ORDER
。当你使用函数作为列时,你需要分组用同样的表达方式。此外,HAVING子句是错误的,你只能使用聚合中的内容。在这种情况下,您的查询应该是这样的:

SELECT 
LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1),
qvalues.name,
qvalues.compound,
MAX(qvalues.rid) MaxRid
FROM batchinfo join qvalues 
ON batchinfo.rowid=qvalues.rowid
WHERE LEN(datapath)>4
GROUP BY 
LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1),
qvalues.name,
qvalues.compound

16
投票

您不能按文字分组,只能按列分组。

您可能正在寻找这样的东西:

select 
LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000), PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1) as pathinfo,
qvalues.name,
qvalues.compound,
qvalues.rid
 from batchinfo join qvalues on batchinfo.rowid=qvalues.rowid
where LEN(datapath)>4
group by pathinfo, qvalues.name, qvalues.compound
having rid!=MAX(rid)

首先,您必须为第一个表达式指定一个带有

as
的列名称。然后,您必须指定 group by 表达式中的列的名称。


6
投票

当我在 SELECT 中有一个“固定”值列时,我收到了此错误消息,作为一个好孩子,我也在 GROUP BY 中使用了它。

例如:

SELECT ID, SUM(Quantity), 'Person'
FROM Persons
GROUP BY ID, 'Person'

修复:

SELECT ID, SUM(Quantity), 'Person'
FROM Persons
GROUP BY ID

固定的

'Person'
值毫无意义,因为它在每一行中都是相同的值,并且没有任何内容可以与该值分组。或者这是我对错误的解释。

我使用这个固定值列的原因是因为我正在准备查询以在数据透视表中使用它。


1
投票

我认为你没有正确使用 GROUP BY。

GROUP BY 的要点是在执行数学/聚合函数之前根据特定列将表组织成多个部分。

例如在此表中:

Name    Age   Salary
Bob     25     20000
Sally   42     40000
John    42     90000

SELECT 语句可以按姓名(Bob、Sally 和 John 分别为单独的组)、年龄(Bob 为一组,Sally 和 John 为另一组)或薪水(结果与姓名几乎相同)进行分组。

按“1”分组没有任何意义,因为“1”不是列名。


1
投票

我刚刚发现这个错误,在选择查询的 group by 子句中使用 GETDATE() [即外部引用]。

当将其替换为相应表中的日期列时,它会被清除。

想作为一个简单的例子来分享。干杯;)


0
投票

当您使用

GROUP BY
时,您还需要对不在 group by 子句内的列使用聚合函数。

我不知道你到底想做什么,但我想这会起作用:

select 
    LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000),
    PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1),
    qvalues.name,
    qvalues.compound,
    MAX(qvalues.rid)
from
    batchinfo join qvalues on batchinfo.rowid=qvalues.rowid
where
    LEN(datapath)>4
group by
    LEFT(SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000),
    PATINDEX('%[^0-9]%', SUBSTRING(batchinfo.datapath, PATINDEX('%[0-9][0-9][0-9]%', batchinfo.datapath), 8000))-1),
    qvalues.name,
    qvalues.compound
having
    rid!=MAX(rid)

编辑: 我在这里想做的是一个包含除

group by
之外的所有字段的
rid
。如果这不是您想要的,为了获得有效的 SQL 语句,您需要做的是为每个删除的按字段分组添加聚合函数调用...


0
投票

这是一个简单的查询,用于查找药品类型为 A 且产量超过 2 的公司名称。

SELECT CNAME 
FROM COMPANY 
WHERE CNO IN (
    SELECT CNO 
    FROM MEDICINE 
    WHERE type='A' 
    GROUP BY CNO HAVING COUNT(type) > 2
)

0
投票

我因为一个愚蠢的错误而收到此错误 - 我的

GROUP BY
列用引号引起来!

错了

GROUP BY 'business'

正确

GROUP BY business

信用:@Sound 的 answer 让我明白了这一点

© www.soinside.com 2019 - 2024. All rights reserved.