无法绑定多部分标识符

时间:2011-09-06 01:29:41

标签: sql sql-server sql-server-2005

我在SO上看到过类似的错误,但我找不到解决问题的方法。 我有一个SQL查询,如:

SELECT DISTINCT
        a.maxa ,
        b.mahuyen ,
        a.tenxa ,
        b.tenhuyen ,
        ISNULL(dkcd.tong, 0) AS tongdkcd
FROM    phuongxa a ,
        quanhuyen b
        LEFT OUTER JOIN ( SELECT    maxa ,
                                    COUNT(*) AS tong
                          FROM      khaosat
                          WHERE     CONVERT(DATETIME, ngaylap, 103) BETWEEN 'Sep 1 2011'
                                                              AND
                                                              'Sep 5 2011'
                          GROUP BY  maxa
                        ) AS dkcd ON dkcd.maxa = a.maxa
WHERE   a.maxa <> '99'
        AND LEFT(a.maxa, 2) = b.mahuyen
ORDER BY maxa;

执行此查询时,错误结果为: 无法绑定多部分标识符“a.maxa”。为什么?
P / s:如果我将查询分成2个单独的查询,则运行正常。

SELECT DISTINCT
        a.maxa ,
        b.mahuyen ,
        a.tenxa ,
        b.tenhuyen
FROM    phuongxa a ,
        quanhuyen b
WHERE   a.maxa <> '99'
        AND LEFT(a.maxa, 2) = b.mahuyen
ORDER BY maxa;

SELECT  maxa ,
        COUNT(*) AS tong
FROM    khaosat
WHERE   CONVERT(DATETIME, ngaylap, 103) BETWEEN 'Sep 1 2011'
                                        AND     'Sep 5 2011'
GROUP BY maxa;

14 个答案:

答案 0 :(得分:200)

您正在将隐式联接与显式联接混合使用。这是允许的,但你需要知道如何正确地做到这一点。

问题是,显式连接(使用JOIN关键字实现的连接)优先于隐式连接('逗号'连接,其中连接条件在WHERE子句中指定)。

以下是您的查询大纲:

SELECT
  …
FROM a, b LEFT JOIN dkcd ON …
WHERE …

你可能希望它表现得像这样:

SELECT
  …
FROM (a, b) LEFT JOIN dkcd ON …
WHERE …

即,表ab的组合与表dkcd连接在一起。事实上,正在发生的事情是

SELECT
  …
FROM a, (b LEFT JOIN dkcd ON …)
WHERE …

也就是说,正如您可能已经理解的那样,dkcd专门针对b加入b,然后加入的结果与a结合使用使用WHERE子句进一步过滤。在这种情况下,a子句中对ON的任何引用都是无效的,a此时未知。这就是您收到错误消息的原因。

如果我是你,我可能会尝试重写这个查询,一个可能的解决方案可能是:

SELECT DISTINCT
  a.maxa,
  b.mahuyen,
  a.tenxa,
  b.tenhuyen,
  ISNULL(dkcd.tong, 0) AS tongdkcd
FROM phuongxa a
  INNER JOIN quanhuyen b ON LEFT(a.maxa, 2) = b.mahuyen
  LEFT OUTER JOIN (
    SELECT
      maxa,
      COUNT(*) AS tong
    FROM khaosat
    WHERE CONVERT(datetime, ngaylap, 103) BETWEEN 'Sep 1 2011' AND 'Sep 5 2011'
    GROUP BY maxa
  ) AS dkcd ON dkcd.maxa = a.maxa
WHERE a.maxa <> '99'
ORDER BY a.maxa

此处首先加入表格ab,然后将结果加入dkcd。基本上,这是与您的查询相同的查询,只对其中一个连接使用不同的语法,这会产生很大的不同:a.maxa的连接条件中的引用dkcd现在绝对有效。

正如@Aaron Bertrand正确指出的那样,你应该在maxa条款中使用特定的别名a来限定ORDER BY

答案 1 :(得分:37)

有时,当您在查询中以错误的方式使用架构(dbo)时会发生此错误。

例如,如果你写:

select dbo.prd.name
from dbo.product prd

你会收到错误。

在这种情况下,请将其更改为:

select prd.name
from dbo.product prd

答案 2 :(得分:7)

我在SQL SERVER中遇到同样的错误信息,因为我有多个连接,更改连接顺序为我解决了这个问题。

答案 3 :(得分:3)

在我的情况下,问题结果是我给表的别名。 &#34; OA&#34;似乎不适合SQL Server。

答案 4 :(得分:2)

我遇到了与JDBC相同的错误。检查了一切,我的查询很好。原来,在哪个条款我有一个论点:

where s.some_column = ?

我传入的参数的值为null。这也会产生同样的错误,这会产生误导,因为当您搜索互联网时,您最终会发现查询结构出现问题,但不是我的情况。只是觉得有人可能会遇到同样的问题

答案 5 :(得分:2)

对我有用的是将WHERE子句更改为SELECT子查询

从:

    DELETE FROM CommentTag WHERE [dbo].CommentTag.NoteId = [dbo].FetchedTagTransferData.IssueId

收件人:

    DELETE FROM CommentTag WHERE [dbo].CommentTag.NoteId = (SELECT NoteId FROM FetchedTagTransferData)

答案 6 :(得分:1)

我是SQL的新手,但在我正在学习的课程中遇到了这个问题,并发现将查询分配给项目特别有助于消除多部分错误。例如,我创建的项目是CTU SQL Project,所以我确保用USE [CTU SQL Project]作为我的第一行开始我的脚本,如下所示。

:b

答案 7 :(得分:1)

如果在 Console.WriteLine(" Enter your scoreCA: "); scoreCA = double.Parse(Console.ReadLine()); Console.WriteLine(" Enter your scoreExam: "); scoreExam = double.Parse(Console.ReadLine()); scoreTotal[i] = scoreExam + scoreCA; for (i=0, i<10, i++; scoreTotal[i] = scoreExam + scoreCA ; if (scoreTotal < 0 || scoreTotal > 100) { Console.WriteLine("invalid"); } else if (scoreTotal <= 100 && scoreTotal > 69) { Console.WriteLine("Your Grade is A"); } else if (scoreTotal < 70 && scoreTotal > 59) { Console.WriteLine("Your grade is B"); } else if (scoreTotal < 60 && scoreTotal > 59) { Console.WriteLine("Your grade is C"); } else if (scoreTotal < 50 && scoreTotal > 44) { Console.WriteLine("Your grade is D"); } else (scoreTotal < 45 && scoreTotal >= 0); { Console.WriteLine("Your grade is F"); Console.ReadKey(); 中发生此错误,请仔细检查表格上的UPDATE,其中包含导致错误的列/字段。

在我的情况下,这是由于缺少JOIN本身,由于未知字段(Andriy pointed out)而产生相同的错误。

答案 8 :(得分:1)

相反,你可以尝试加入像

这样的表格
ggplot(df, aes(x, y, fill = z)) + geom_raster() +
  scale_fill_gradient2( low = "#2166ac", mid = "#f7f7f7", high = "#b2182b", midpoint = 0.2, 
                        space = "Lab", na.value = "grey50", guide = "colourbar")

这应该有效

答案 9 :(得分:1)

SELECT DISTINCT
        phuongxa.maxa ,
        quanhuyen.mahuyen ,
        phuongxa.tenxa ,
        quanhuyen.tenhuyen ,
        ISNULL(dkcd.tong, 0) AS tongdkcd
FROM    phuongxa ,
        quanhuyen
        LEFT OUTER JOIN ( SELECT    khaosat.maxa ,
                                    COUNT(*) AS tong
                          FROM      khaosat
                          WHERE     CONVERT(DATETIME, ngaylap, 103) BETWEEN 'Sep 1 2011'
                                                              AND
                                                              'Sep 5 2011'
                          GROUP BY  khaosat.maxa
                        ) AS dkcd ON dkcd.maxa = maxa
WHERE   phuongxa.maxa <> '99'
        AND LEFT(phuongxa.maxa, 2) = quanhuyen.mahuyen
ORDER BY maxa;

答案 10 :(得分:1)

我的错误是使用表中不存在的字段。

table1.field1 =&gt;不存在

table2.field1 =&gt;是正确的

更正您的表名。

由于使用了WITH

,我的错误发生了
WITH RCTE AS (
   SELECT...
)
SELECT RCTE.Name, ...
FROM 
  RCTE INNER JOIN Customer
  ON RCTE.CustomerID = Customer.ID 

用于与其他表的连接...

答案 11 :(得分:1)

你有没有忘记加入一些桌子?如果没有,那么你可能需要使用一些别名。

答案 12 :(得分:1)

我也在这个错误中挣扎,最终得到了与答案相同的策略。我加入我的答案只是为了确认这是一个行之有效的策略。

这里是一个示例,其中我先在两个我知道有数据的表之间执行一个内部联接,然后在可能具有对应行可以为空的表上进行两个左外部联接。您可以混合使用内部联接和外部联接来获得跨表数据的结果,而不是在表之间执行默认的逗号分隔语法,从而错过所需联接中的行。

use somedatabase
go 

select o.operationid, o.operatingdate, p.pasid, p.name as patientname, o.operationalunitid, f.name as operasjonsprogram,  o.theaterid as stueid, t.name as stuenavn, o.status as operasjonsstatus from operation o 
inner join patient p on o.operationid = p.operationid 
left outer join freshorganizationalunit f on f.freshorganizationalunitid = o.operationalunitid
left outer join theater t on t.theaterid = o.theaterid
where (p.Name like '%Male[0-9]%' or p.Name like '%KFemale [0-9]%')

首先:在您希望数据匹配的表之间进行内部联接。 第二部分:继续进行外部联接以尝试检索其他表中的数据, 但是,如果表外部联接没有得到相应的数据或不符合您在on谓词/条件中设置的条件,则此操作不会过滤出结果集。

答案 13 :(得分:0)

此错误也可能是由于在SELECT语句中的列名称之间仅缺少逗号,而引起的。

例如:

SELECT MyCol1, MyCol2 MyCol3 FROM SomeTable;