बहु-भाग पहचानकर्ता बाध्य नहीं हो सकता है


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?
माइकल पेट्रोत्ता

1
क्या होता है यदि आप अधिकतम 5, 2011 के बाद से अधिकतम, जीभ द्वारा समूह जोड़ते हैं।
user710502

हाँ, यह है। अगर मैं क्वेरी को 2 सबक्वेरी में विभाजित करता हूं, तो यह ठीक है
PhamMinh

लगता है कि आप गलत डेटाबेस पर अमल कर रहे हैं। क्वेरी की शुरुआत में "USE [डेटाबेस नाम]" स्टेटमेंट जोड़ें और देखें कि क्या आपको अभी भी त्रुटि मिलती है।
ब्रायन

1
नहीं, मैंने ऊपर कहा था, अगर मैं क्वेरी को 2 अलग-अलग क्वेरी में विभाजित करता हूं, तो यह ठीक चलता है।
फम्मिन

जवाबों:


226

आप स्पष्ट जोड़ के साथ निहित जोड़ मिला रहे हैं। यह अनुमति है, लेकिन आपको ठीक से कैसे करना है, इसके बारे में पता होना चाहिए।

बात यह है कि, स्पष्ट रूप से जुड़ने वाले ( JOINकीवर्ड का उपयोग करके लागू किए जाने वाले) अंतर्निहित लोगों पर पूर्वता लेते हैं ('अल्पविराम' जुड़ते हैं, जहां WHEREक्लॉज में शामिल होने की स्थिति निर्दिष्ट होती है )।

यहां आपकी क्वेरी की रूपरेखा दी गई है:

SELECT
  
FROM a, b LEFT JOIN dkcd ON 
WHERE 

आप शायद इस तरह से व्यवहार करने की उम्मीद कर रहे हैं:

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

वह है, तालिकाओं का संयोजन aऔर bतालिका के साथ जुड़ जाता है 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

यहां टेबल aऔर bपहले शामिल हो गए, फिर परिणाम में शामिल हो गया dkcd। मूल रूप से, यह आपकी ही क्वेरी है, केवल एक जोड़ के लिए एक अलग वाक्यविन्यास का उपयोग करते हुए, जो बहुत अच्छा बदलाव करता है: 's जॉइन कंडीशन' a.maxaमें संदर्भ dkcdअब बिल्कुल मान्य है।

जैसा कि @Aaron बर्ट्रेंड ने सही उल्लेख किया है, आपको संभवतः maxaएक विशिष्ट उपनाम के साथ अर्हता प्राप्त करनी चाहिए , शायद a, ORDER BYखंड में।


अधिकतम द्वारा आदेश अभी भी अस्पष्ट है, नहीं? इसके अलावा, मैं एक तारीख के रूप में 'सितम्बर 1 2011' के साथ सावधान रहूंगा, विभिन्न भाषाओं / क्षेत्रीय सेटिंग्स के साथ काम नहीं करूंगा।
एरॉन बर्ट्रेंड

@ ऐरन: ORDER BY maxaधन्यवाद के बारे में , धन्यवाद। तारीखों के लिए, मेरा मानना ​​है कि ओपी ने उन्हें अपने वातावरण में निर्दिष्ट करने के लिए कैसे चुना है।
एंड्री एम।

"स्पष्ट जुड़ता है ... निहितार्थ पर पूर्वता बरतें" - क्या आप इसके लिए प्रशस्ति पत्र प्रदान कर सकते हैं, कृपया? उदाहरण के लिए, यह एसक्यूएल मानकों में परिभाषित है या यह एक उत्पाद विशेषता है? धन्यवाद।
onedaywhen

1
@onedaywhen: मुझे डर है कि यह अब तक मेरी ओर से अवलोकन से अधिक नहीं है। मैं इस तथ्य से कुछ हद तक राहत महसूस कर रहा हूं कि मैं यहां पहले से जुड़ने के बारे में बात नहीं कर रहा हूं , लेकिन इसके अलावा, मुझे किसी भी तरह की आधिकारिक पुष्टि मिलने पर खुशी होगी।
एंड्री एम।

1
मेरे मामले में, मैं रिक्त स्थान रखना भूल गया था जब मैंने एसक्यूएल का निर्माण करने के लिए तारों को संक्षिप्त किया था, इसलिए 'FROM dbo.table_a a' + 'INNER JOIN dbo.table_b b' से 'FROM dB.table_a ainNER JOIN dbo.table_b b' बन गया, और यह भ्रमित हो गया और मुझे यह त्रुटि संदेश दिया। विवरण, विवरण, विवरण।
गाइ शालनाट

40

कभी-कभी यह त्रुटि तब होती है जब आप अपने क्वेरी में अपने स्कीमा (dbo) का उपयोग गलत तरीके से करते हैं।

उदाहरण के लिए यदि आप लिखते हैं:

select dbo.prd.name
from dbo.product prd

आपको त्रुटि मिलेगी।

इस स्थितियों में इसे बदल सकते हैं:

select prd.name
from dbo.product prd

1
यह काफी कष्टप्रद है और मुझे इसका पता लगाने में बहुत लंबा समय लगा। Thanx। सबसे कष्टप्रद हिस्सा कभी कभी यह इस लेकिन अन्य समय के बारे में naggs यह normaly गुजरता है
DanteTheSmith

12

यदि आपने उपनाम नाम बदल दिया है, तो वास्तविक नाम में

उदाहरण के लिए

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 स्ट्रिंग का निर्माण कर रहे हैं, तो लाइन के अंत में अनुगामी रिक्त स्थान की कमी को देखें। इसने मेरे उपनाम M को MINNER में तब परिवर्तित कर दिया जब यह नीचे की अगली INNER JOIN लाइन में शामिल हो गया। एसक्यूएल प्रोफाइलर ने दिखाया स्ट्रिंग को निष्पादित करने से मेरी समस्या को हल करने में मदद मिली। (यहाँ टिप्पणी के रूप में यह उपनाम वि वास्तविक नाम मुद्दे से संबंधित है)
सिमोन

वाह @Simon धन्यवाद मैंने भी इस बारे में नहीं सोचा था और दीवार के खिलाफ मेरे सिर को पीटने की कोशिश कर रहा था कि मेरी क्वेरी क्यों काम नहीं कर रही थी, मैं स्ट्रिंग गाड़ी के रिटर्न में से एक के अंत में एक स्थान याद कर रहा था!
बोझ

9

मैं SQL सर्वर में एक ही त्रुटि संदेश के साथ संघर्ष कर रहा था, क्योंकि मेरे पास कई जोड़ थे, जो कि मेरे द्वारा हल किए गए जोड़ के क्रम को बदल रहे थे।


3

मेरे मामले में यह मुद्दा उर्फ ​​नाम था जो मैंने तालिका को दिया था। SQL सर्वर के लिए "oa" स्वीकार्य नहीं लगता है।


2

मुझे JDBC से वही त्रुटि हो रही थी। सब कुछ चेक किया और मेरी क्वेरी ठीक थी। पता चला, कि किस खंड में मेरा तर्क है:

where s.some_column = ?

और मैं जिस तर्क से गुजर रहा था उसका मूल्य शून्य था। यह भी वही त्रुटि देता है जो भ्रामक है क्योंकि जब आप इंटरनेट खोजते हैं तो आप अंत में कहते हैं कि क्वेरी संरचना के साथ कुछ गलत है लेकिन यह मेरे मामले में नहीं है। बस सोचा कि किसी को एक ही मुद्दे का सामना करना पड़ सकता है


2

मेरे लिए जो काम किया, वह था कि मैं अपने चयन खंड में चयन को कहां बदलूं

से:

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

सेवा:

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

1

मैं एसक्यूएल के लिए नया हूं, लेकिन इस मुद्दे पर आया था एक कोर्स में मैं ले रहा था और पाया कि प्रोजेक्ट को क्वेरी असाइन करना विशेष रूप से मल्टी-पार्ट त्रुटि को खत्म करने में मदद करता है। उदाहरण के लिए मैंने जो प्रोजेक्ट बनाया था वह सीटीयू एसक्यूएल प्रोजेक्ट था इसलिए मैंने सुनिश्चित किया कि मैंने अपनी स्क्रिप्ट का उपयोग नीचे की तरह अपनी पहली पंक्ति के रूप में यूएसई [सीटीयू एसक्यूएल प्रोजेक्ट] के साथ शुरू किया।

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

1
जब आप कहते हैं कि "प्रोजेक्ट" मैं मानता हूं कि आप डेटाबेस का मतलब है और प्रक्षेपण नहीं। उपयोग स्टेटमेंट केवल यह
बताता है

हाँ, चारलेह परियोजना के रूप में डेटाबेस में मैं काम कर रहा था। मुझे यकीन नहीं था कि मैं अपने डेटाबेस के साथ क्या गलत कर रहा हूं, लेकिन "उपयोग" और विशिष्ट डेटाबेस को मेरी गलती को समाप्त करने के लिए कहा।
बोगार्ट्ज

1

यदि यह त्रुटि होती है UPDATE, JOINतो त्रुटि उत्पन्न करने वाले कॉलम / फ़ील्ड के साथ तालिका पर डबल-चेक करें ।

मेरे मामले में यह JOINस्वयं की कमी के कारण था , जिसने अज्ञात क्षेत्र के कारण एक ही त्रुटि उत्पन्न की (जैसा कि एंड्री ने बताया )।


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

1

मेरी त्रुटि एक ऐसे क्षेत्र का उपयोग करने की थी जो तालिका में मौजूद नहीं था।

table1.field1 => मौजूद नहीं है

table2.field1 => सही है

अपनी तालिका का नाम ठीक करें।

के साथ उपयोग करने के कारण मेरी त्रुटि हुई

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

जब अन्य तालिकाओं के साथ शामिल होने के लिए ...


1

क्या आप कुछ तालिकाओं में शामिल होना भूल गए? यदि नहीं, तो आपको शायद कुछ उपनामों का उपयोग करने की आवश्यकता है।


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

पहला: क्या आप उन मेलों के बीच में जुड़ते हैं जिनसे आपको डेटा मिलान की उम्मीद है। दूसरा भाग: अन्य तालिकाओं में डेटा को पुनः प्राप्त करने की कोशिश करने के लिए बाहरी जोड़ के साथ जारी रखें, लेकिन यह आपके परिणाम को फ़िल्टर नहीं करेगा यदि तालिका बाहरी जुड़ने को उसी डेटा या मैच के लिए नहीं मिला है जिसे आप विधेय / शर्त पर सेट करते हैं।


0

यह त्रुटि केवल ,SELECT स्टेटमेंट में कॉलम नामों के बीच अल्पविराम याद करने के कारण भी हो सकती है ।

उदाहरण के लिए:

SELECT MyCol1, MyCol2 MyCol3 FROM SomeTable;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.