分组条款问题

时间:2011-09-19 22:10:40

标签: sql sql-server

我在访问中编写了一个查询,现在我正在尝试在SQL Server中编写相同的内容我遇到以下错误:

  

Msg 164,Level 15,State 1,Procedure OQRY_STEP_1_1,第15行   每个GROUP BY表达式必须至少包含一个不是外部引用的列。

我的SQL查询如下:

SELECT
    ns11.SYS_ID,
    ns11.SUB_NET_ID,
    ns11.TEMP_ID,
    ns11.EQ_ID,
    ns11.NODE_NAME,
    ns11.EQ_NAME,
    ns11.VAR_NAME,
    ns11.VAR_SET,
    ns11.VAR_SUBSET,
    ns11.EQ_TYPE,
    ns11.RHS_RELN,
    ns11.RHS_OBJECT,
    ns11.EQ_TP_OFFSET,
    ns11.RHS_TP_OFFSET,
    ns11.RETAIN,
    nmte.RHS_VAR_SET,
    nmte.RHS_VAR_SUBSET,
    nmte.RHS_VAR_NAME,
    0 AS RHS_VAR_TYPE,
    CASE
        WHEN [asp].[VALUE] = NULL THEN 0
        ELSE [asp].[VALUE]
    END RHS_VALUE
INTO ##OT_STEP_1_1
FROM (##NT_STEP_1_1 ns11
    INNER JOIN ##NT_MASTER_TEMP_EQUATION nmte
        ON (ns11.SYS_ID = nmte.SYS_ID)
            (ns11.SUB_NET_ID = nmte.SUB_NET_ID)
        AND (ns11.TEMP_ID = nmte.TEMP_ID)
        AND (ns11.EQ_ID = nmte.EQ_ID)
        AND (ns11.NODE_NAME = nmte.NODE_NAME)
        AND (nmte.SYS_ID = ns11.SYS_ID)
        AND (nmte.SUB_NET_ID = ns11.SUB_NET_ID))
    LEFT JOIN AMST_SIM_PAR asp ON 
        (nmte.SYS_ID = asp.SYS_ID)
        AND (nmte.SUB_NET_ID = ns11.SUB_NET_ID)
        AND (nmte.RHS_VAR_NAME = asp.VAR_NAME)
GROUP BY
    ns11.SYS_ID,
    ns11.SUB_NET_ID,
    ns11.TEMP_ID,
    ns11.EQ_ID,
    ns11.NODE_NAME,
    ns11.EQ_NAME,
    ns11.VAR_NAME,
    ns11.VAR_SET,
    ns11.VAR_SUBSET,
    ns11.EQ_TYPE,
    ns11.RHS_RELN,
    ns11.RHS_OBJECT,
    ns11.EQ_TP_OFFSET,
    ns11.RHS_TP_OFFSET,
    ns11.RETAIN,
    nmte.RHS_VAR_SET,
    nmte.RHS_VAR_SUBSET,
    nmte.RHS_VAR_NAME,
    0,
    CASE
        WHEN [asp].[VALUE] = NULL THEN 0
        ELSE [asp].[VALUE]
    END
ORDER BY
    CASE
        WHEN [asp].[VALUE] = NULL THEN 0
        ELSE [asp].[VALUE]
    END;

我不确定为什么它不是在group by子句中取0?

3 个答案:

答案 0 :(得分:1)

我认为你的小组中的常数'0'是问题所在。

您使用的是ANSI_NULLS吗? SQL-92定义“= NULL”或“<> NULL”以始终返回false。尝试将“= NULL”更改为“IS NULL”。

同样在左连接中,您的条件与外部表格不匹配。内连接已经链接了这两个表上的SUB_NET_ID,因此您可以从左连接中删除它。

答案 1 :(得分:1)

我认为GROUP BY ..., 0, ...是问题所在。尝试从那里删除0。通过常数没有点分组。


旁注:

CASE WHEN [AMST_SIM_PAR].[VALUE] = NULL
THEN 0
ELSE [AMST_SIM_PAR].[VALUE]
END

应使用IS NULL代替= NULL或<:p>

COALESCE( [AMST_SIM_PAR].[VALUE], 0 )

答案 2 :(得分:0)

由于您没有收集任何汇总,为什么不使用DISTINCT而不是重复GROUP BY中的所有噪音?此外,ORDER BY不是很有用,因为您正在使用SELECT INTO,它会创建一个新表,根据定义,它是一组无序行。为了以正确的“顺序”从该表中获取数据,当您最终选择它时,应该使用ORDER BY。如果您希望为连接优化数据或创建表后的内容,请在SELECT INTO之后创建聚簇索引。最后,为什么使用##全局临时表?您知道两个用户无法同时执行此代码,对吧?

所有这一切,这是一个更简单易读的版本:

SELECT DISTINCT 
    n.SYS_ID, 
    n.SUB_NET_ID, 
    n.TEMP_ID, 
    n.EQ_ID, 
    n.NODE_NAME, 
    n.EQ_NAME, 
    n.VAR_NAME, 
    n.VAR_SET, 
    n.VAR_SUBSET, 
    n.EQ_TYPE, 
    n.RHS_RELN, 
    n.RHS_OBJECT, 
    n.EQ_TP_OFFSET, 
    n.RHS_TP_OFFSET, 
    n.RETAIN, 
    te.RHS_VAR_SET, 
    te.RHS_VAR_SUBSET, 
    te.RHS_VAR_NAME, 
    RHS_VAR_TYPE = 0, 
    RHS_VALUE = COALESCE(a.VALUE, 0)
INTO ##OT_STEP_1_1
FROM ##NT_STEP_1_1 AS n
INNER JOIN ##NT_MASTER_TEMP_EQUATION AS te
        ON n.SYS_ID = te.SYS_ID
        AND n.SUB_NET_ID = te.SUB_NET_ID 
        AND n.TEMP_ID = te.TEMP_ID 
        AND n.EQ_ID = te.EQ_ID
        AND n.NODE_NAME = te.NODE_NAME 
        AND te.SYS_ID = n.SYS_ID
        AND te.SUB_NET_ID = n.SUB_NET_ID
LEFT OUTER JOIN dbo.AMST_SIM_PAR AS a 
        ON te.SYS_ID = a.SYS_ID
        AND te.SUB_NET_ID = n.SUB_NET_ID
        AND te.RHS_VAR_NAME = a.VAR_NAME;