运行查询时列名无效

时间:2014-11-27 13:52:41

标签: sql sql-server

我是SQL新手,我不知道此查询中有什么错误,

SELECT 
    wo.WORKORDERID "Request ID", (wo.CREATEDTIME) "Created on", 
    aau.FIRST_NAME "Requester", aac.EMAILID 'From', 
    [To] = STUFF((SELECT ', ' + Recipient_email 
                  FROM workorder_recipients wor2 
                  WHERE wor2.Workorderid = wor.Workorderid and wor2.To_cc_bcc='To' 
                  FOR XML PATH('')), 1, 2, ''), 
    [CC] = STUFF((SELECT ', ' + Recipient_email 
                  FROM workorder_recipients wor2
                  WHERE wor2.Workorderid = wor.Workorderid and wor2.To_cc_bcc='CC' 
                  FOR XML PATH('')), 1, 2, ''),
    cd.CATEGORYNAME "Category" 
FROM 
    workorder_recipients wor
LEFT JOIN 
    workorder wo ON wor.workorderid = wo.workorderid 
LEFT JOIN 
    ModeDefinition mdd ON wo.MODEID = mdd.MODEID 
LEFT JOIN 
    SDUser sdu ON wo.REQUESTERID = sdu.USERID 
LEFT JOIN 
    AaaUser aau ON sdu.USERID = aau.USER_ID 
LEFT JOIN 
    SDUser crd ON wo.CREATEDBYID = crd.USERID 
LEFT JOIN 
    AaaUser cri ON crd.USERID = cri.USER_ID 
LEFT JOIN 
    AaaUserContactInfo aauc ON aau.USER_ID = aauc.USER_ID 
LEFT JOIN 
    AaaContactInfo aac ON aauc.CONTACTINFO_ID = aac.CONTACTINFO_ID 
LEFT JOIN 
    WorkOrderStates wos ON wo.WORKORDERID = wos.WORKORDERID 
LEFT JOIN 
    CategoryDefinition cd ON wos.CATEGORYID = cd.CATEGORYID 
WHERE 
    mdd.MODENAME = 'E-Mail'
    AND cd.CATEGORYNAME in ('Agent Operational Technology (EMEA/UK/IE)','Client Technology')
    AND wo.IS_CATALOG_TEMPLATE='0'
    AND wo.CREATEDTIME >= 1416783600000 
    AND wo.CREATEDTIME <= 1417388399000
    AND wo.ISPARENT='1' 
GROUP BY 
    wo.workorderid 

但我一直收到这个错误:

  

列&#39; workorder_recipients.WORKORDERID&#39;在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

谢谢, 阿图尔

2 个答案:

答案 0 :(得分:3)

想象一下以下简单表(T),其中ID是主键:

ID  | Column1 | Column2  |
----|---------+----------|
1   |    A    |    X     |
2   |    A    |    Y     |

然后你写下面的查询

SELECT  ID, Column1, Column2
FROM    T
GROUP BY Column1;

这打破了SQL标准,如果它运行没有错误(在MySQL中会运行),结果是:

ID  | Column1 | Column2  |
----|---------+----------|
1   |    A    |    X     |

不比

更正确或更不正确
ID  | Column1 | Column2  |  
----|---------+----------|
2   |    A    |    Y     |

所以你要说的是Column1的每个不同值给我一行,两个结果集都满足,所以你怎么知道你会得到哪一个?好吧,你不要。

为了简单起见(以及它在SQL Server中的实现方式),我们声明了如果一个列未包含在聚合函数中的规则,它必须在GROUP BY子句中才能显示在选择列表中。这并非严格正确,SQL-Standard允许选择列表中的列不包含在GROUP BY中或聚合函数中,但是这些列必须在功能上依赖于GROUP BY中的列。从SQL-2003-Standard(5WD-02-Foundation-2003-09-第346页) - http://www.wiscorp.com/sql_2003_standard.zip

  

15)如果T是分组表,那么让G成为T的分组列的集合   在,引用T列的每个列引用应引用某些C列   在功能上依赖于G或应包含在a的聚合参数中   其聚合查询为QS。

例如,示例表中的ID是PRIMARY KEY,因此我们知道它在表中是唯一的,因此以下查询符合SQL标准并且将在MySQL中运行并且在当前的许多DBMS中失败(当时写作Postgresql是我所知道的最接近正确实施标准的DBMS - Example here):

SELECT  ID, Column1, Column2
FROM    T
GROUP BY ID;

由于ID对于每一行都是唯一的,因此每个ID只能有一个值Column1,一个值Column2没有歧义 每行返回什么。据我所知,Postgresql是唯一一个实现此目的的DBMS。

为了使您的查询有效,您需要在GROUP BY

中添加一些列
GROUP BY wo.workorderid, wo.CREATEDTIME, aau.FIRST_NAME, aac.EMAILID, cd.CATEGORYNAME

但是,我认为您可以通过从workorder_recipients删除FROM来解决重复问题,但您似乎无法在任何地方使用此问题。删除此引用应取消对GROUP BY

的需求
SELECT 
    [Request ID] = wo.WORKORDERID, 
    [Created on] = wo.CREATEDTIME, 
    [Requester] = aau.FIRST_NAME, 
    [From] = aac.EMAILID, 
    [To] = STUFF((SELECT ', ' + Recipient_email 
                  FROM workorder_recipients wor2 
                  WHERE wor2.Workorderid = wo.Workorderid 
                  AND wor2.To_cc_bcc='To' 
                  FOR XML PATH('')), 1, 2, ''), 
    [CC] = STUFF((SELECT ', ' + Recipient_email 
                  FROM  workorder_recipients wor2
                  WHERE wor2.Workorderid = wo.Workorderid 
                  AND   wor2.To_cc_bcc='CC' 
                  FOR XML PATH('')), 1, 2, ''),
    [Category] = cd.CATEGORYNAME 
FROM workorder wo
    LEFT JOIN ModeDefinition AS mdd 
        ON wo.MODEID = mdd.MODEID 
    LEFT JOIN SDUser AS sdu 
        ON wo.REQUESTERID = sdu.USERID 
    LEFT JOIN AaaUser AS aau 
        ON sdu.USERID = aau.USER_ID 
    LEFT JOIN SDUser AS crd 
        ON wo.CREATEDBYID = crd.USERID 
    LEFT JOIN AaaUser AS cri 
        ON crd.USERID = cri.USER_ID 
    LEFT JOIN AaaUserContactInfo AS aauc 
        ON aau.USER_ID = aauc.USER_ID 
    LEFT JOIN AaaContactInfo AS aac 
        ON aauc.CONTACTINFO_ID = aac.CONTACTINFO_ID 
    LEFT JOIN WorkOrderStates AS wos 
        ON wo.WORKORDERID = wos.WORKORDERID 
    LEFT JOIN CategoryDefinition AS cd 
        ON wos.CATEGORYID = cd.CATEGORYID 
WHERE 
    mdd.MODENAME = 'E-Mail'
    AND cd.CATEGORYNAME in ('Agent Operational Technology (EMEA/UK/IE)','Client Technology')
    AND wo.IS_CATALOG_TEMPLATE='0'
    AND wo.CREATEDTIME >= 1416783600000 
    AND wo.CREATEDTIME <= 1417388399000
    AND wo.ISPARENT='1';

答案 1 :(得分:0)

在查询中使用GROUP BY时,您需要在选择中包含组中的每个字段,但您要汇总的字段除外 - 例如SUM a MINMAX(其中包括)。

所以,设想一个例子,这将是无效的:

SELECT FirstName, LastName, SUM(Score)
FROM HighScores
GROUP BY FirstName

您还需要在LastName中加入GROUP BY以获取某人的总分