マルチパート識別子をバインドできませんでした


196

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;

ないphuongxaテーブルには列が含まれますかmaxa
Michael Petrotta、2011


はい、あります。クエリを2つのサブクエリに
分割

間違ったデータベースで実行しているようです。クエリの先頭に「USE [データベース名]」ステートメントを追加し、それでもエラーが発生するかどうかを確認します。
ブライアン、2011

1
いいえ、上で述べましたが、クエリを2つの個別のクエリに分割すると、okeyが実行されます。
PhamMinh、2011

回答:


226

暗黙的な結合と明示的な結合が混在しています。それは許可されていますが、適切にそれを行う方法を認識する必要があります。

問題は、明示的な結合(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.maxadkcdの条件は今絶対に有効で参加します。

@Aaron Bertrandが正しく指摘しているようにmaxa、おそらく句のa中の特定のエイリアス(おそらく)で修飾する必要がありますORDER BY


ORDER BY maxaはまだあいまいです、いいえ?また、日付として「2011年9月1日」を使用する場合は注意が必要です。別の言語/地域設定では機能しません。
アーロンバートランド

@Aaron:同意しますORDER BY maxa、ありがとう。日付に関しては、それがOPが環境でそれらを指定するために選択した方法だと私は信じています。
Andriy M

「明示的な結合...暗黙的な結合よりも優先されます」-これについての引用を提供できますか?たとえば、SQL標準で定義されているのですか、それとも製品の機能ですか。ありがとう。
2011

1
@onedaywhen:これは、これまでのところ私の側の観察にすぎません。ここでは、結合の優先順位について最初に話したのではないので、多少は安心しましたが、それ以外は、自分で何らかの公式の確認を見つけられてうれしいです。
Andriy M

1
私の場合、文字列を連結してSQLを構築するときにスペースを入れるのを忘れていたので、 'FROM dbo.table_a a' + 'INNER JOIN dbo.table_b b'は 'FROM dbo.table_a aINNER JOIN dbo.table_b b'になりました。混乱して、このエラーメッセージが表示されました。詳細、詳細、詳細。
Guy Schalnat 2017

40

クエリでスキーマ(dbo)を間違った方法で使用すると、このエラーが発生することがあります。

たとえば、次のように書いた場合:

select dbo.prd.name
from dbo.product prd

エラーが発生します。

この状況では、次のように変更します。

select prd.name
from dbo.product prd

1
これは非常に迷惑なものであり、理解するのに時間がかかりすぎました。ありがとう。最も厄介な部分は、これについて時々ナグドですが、それ以外の場合は正常に通過します
DanteTheSmith

12

alies名を付けている場合は、実際の名前に変更します

例えば

SELECT  
    A.name,A.date
  FROM [LoginInfo].[dbo].[TableA] as A
   join 
  [LoginInfo].[dbo].[TableA] as B 
  on  [LoginInfo].[dbo].[TableA].name=[LoginInfo].[dbo].[TableB].name;

に変更

SELECT  
    A.name,A.date
  FROM [LoginInfo].[dbo].[TableA] as A
   join 
  [LoginInfo].[dbo].[TableA] as B 
  on  A.name=B.name;

1
また、SQL文字列を作成している場合は、行末に末尾のスペースがないことに注意してください。それが次のINNER JOIN行に加わったときに、エイリアスMをMINNERに変換しました。実行された文字列を示すSQLプロファイラーが問題の解決に役立ちました。(エイリアスと実際の名前の問題に関連するため、ここでコメントしました)
Simon

すごい@Simonありがとう、私はこれについてさえ考えず、壁に頭をぶつけて、クエリが機能しなかった理由を理解しようとしました。文字列キャリッジリターンの1つの終わりにスペースがありませんでした。
buradd

9

SQL SERVERで同じエラーメッセージに悩まされていました。複数の結合があったため、結合順序を変更すると解決しました。


3

私の場合、問題は私がテーブルに付けたエイリアス名であることがわかりました。"oa"はSQL Serverでは受け入れられないようです。


2

JDBCからも同じエラーが発生しました。すべてをチェックし、私のクエリは大丈夫でした。結局のところ、where句には引数があります。

where s.some_column = ?

そして、私が渡した引数の値はnullでした。これはまた、インターネットを検索するとクエリ構造に何かが間違っているということになるので、誤解を招く同じエラーが発生しますが、私の場合はそうではありません。誰かが同じ問題に直面するかもしれないと思った


2

私にとってうまくいったのは、WHERE句をSELECTサブクエリに変更することでした

から:

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

に:

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

1

SQLは初めてですが、コースでこの問題に遭遇しましたが、クエリをプロジェクトに割り当てると、特にマルチパートエラーを排除できることがわかりました。たとえば、私が作成したプロジェクトはCTU SQLプロジェクトだったので、以下のように最初の行としてUSE [CTU SQL Project]を使用してスクリプトを開始したことを確認しました。

USE [CTU SQL Project]
SELECT Advisors.First_Name, Advisors.Last_Name...and so on.

1
あなたが「プロジェクト」と言うとき、私はあなたがデータベースではなく投影を意味していると思います。useステートメントは、クエリをスコープするデータベースを変更するだけです
Charleh

はい、私が作業していたデータベースと同じように、Charlehプロジェクト。データベースで何が悪いのかわからなかったのですが、「使用」と特定のデータベースのスコープを指定することでエラーが解消されました。
Bogartz 2016年

1

このエラーがで発生する場合は、エラーの原因となっている列/フィールドを含むテーブルでを再UPDATE確認しJOINてください。

私の場合、これはJOINそれ自体の欠如が原因でしたが、未知のフィールドが原因で同じエラーが発生しました(Andriyが指摘したように)。


1

代わりに、次のようなテーブルの結合を試すことができます:

select 
  .... 
from 
   dkcd 
     right join 
                a
                  , b

これはうまくいくはずです


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;

マルチパートバインドの問題が発生した場合は、エイリアスではなくテーブル名自体を使用します。
SVaidya 2017

1

私のエラーは、テーブルに存在しないフィールドを使用することでした。

table1.field1 =>は存在しません

table2.field1 =>は正しい

テーブル名を修正してください。

WITHを使用したためにエラーが発生しました

WITH RCTE AS (
   SELECT...
)
SELECT RCTE.Name, ...
FROM 
  RCTE INNER JOIN Customer
  ON RCTE.CustomerID = Customer.ID 

他のテーブルとの結合で使用した場合...


1

いくつかのテーブルを結合するのを忘れましたか?そうでない場合は、おそらくいくつかのエイリアスを使用する必要があります。


1

私もこのエラーに苦労していて、答えと同じ戦略になりました。これが機能する戦略であることを確認するためだけに、私の回答を含めています。

これは、データを取得したことがわかっている2つのテーブル間で最初に1つの内部結合を実行し、次に、対応する行が空になる可能性があるテーブルで2つの左外部結合を実行する例です。テーブル間でデフォルトのコンマ区切りの構文を実行する代わりに、内部結合と外部結合を混合して、テーブル全体のデータで結果を取得し、目的の結合で行を逃します。

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]%')

最初に、データの一致が予想されるテーブル間の内部結合を実行します。2番目の部分:外部結合を続行して他のテーブルのデータを取得しようとしますが、外部結合先のテーブルが対応するデータを取得していないか、述語/条件で設定した条件に一致しない場合、結果セットは除外されません。


0

このエラーは、単にカンマがないことによっても発生します。 ,、SELECTステートメントの列名の間に。

例えば:

SELECT MyCol1, MyCol2 MyCol3 FROM SomeTable;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.