El identificador de varias partes no se pudo vincular

196

He visto errores similares en SO, pero no encuentro una solución para mi problema. Tengo una consulta SQL como:

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;

Cuando ejecuto esta consulta, el resultado del error es: El identificador de varias partes "a.maxa" no se pudo vincular. ¿Por qué?
P / s: si divido la consulta en 2 consultas individuales, se ejecuta bien.

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;

y

SELECT  maxa ,
        COUNT(*) AS tong
FROM    khaosat
WHERE   CONVERT(DATETIME, ngaylap, 103) BETWEEN 'Sep 1 2011'
                                        AND     'Sep 5 2011'
GROUP BY maxa;
PhamMinh
fuente
¿La phuongxatabla incluye una columna maxa?
Michael Petrotta
1
¿Qué sucede si agrega un grupo por maxa, tong? Justo después del 5 de septiembre de 2011.
user710502
Si lo ha hecho. Si dividí la consulta a 2 subconsultas, se ejecuta bien
PhamMinh
Parece que está ejecutando en la base de datos incorrecta. Agregue una instrucción "USE [nombre de la base de datos]" al comienzo de la consulta y vea si aún recibe el error.
brian
1
No, dije anteriormente, si divido la consulta en 2 consultas individuales, se ejecuta okey.
PhamMinh

Respuestas:

226

Está mezclando combinaciones implícitas con combinaciones explícitas. Eso está permitido, pero debe ser consciente de cómo hacerlo correctamente.

La cuestión es que las uniones explícitas (las que se implementan usando la JOINpalabra clave) tienen prioridad sobre las implícitas (las uniones de 'coma', donde la condición de unión se especifica en la WHEREcláusula).

Aquí hay un resumen de su consulta:

SELECT
  
FROM a, b LEFT JOIN dkcd ON 
WHERE 

Probablemente espere que se comporte así:

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

es decir, la combinación de tablas ay bse une con la tabla dkcd. De hecho, lo que está sucediendo es

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

es decir, como ya habrá entendido, dkcdse une específicamente contra by solo b, luego el resultado de la combinación se combina ay se filtra más con la WHEREcláusula. En este caso, cualquier referencia aa en la ONcláusula es inválida, aes desconocida en ese punto. Es por eso que recibe el mensaje de error.

Si yo fuera usted, probablemente intentaría reescribir esta consulta, y una posible solución podría ser:

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

Aquí las tablas ay bse unen primero, luego el resultado se une adkcd . Básicamente, esta es la misma consulta que la suya, solo que usa una sintaxis diferente para una de las uniones, lo que hace una gran diferencia: la referencia a.maxaen la dkcdcondición de unión ahora es absolutamente válida.

Como @Aaron Bertrand ha notado correctamente, probablemente debería calificar maxacon un alias específico, probablemente a, en la ORDER BYcláusula.

Andriy M
fuente
ORDER BY maxa sigue siendo ambiguo, ¿no? También tendría cuidado con 'Sep 1 2011' como fecha, no funcionará con diferentes idiomas / configuraciones regionales.
Aaron Bertrand
@ Aaron: De acuerdo ORDER BY maxa, gracias. En cuanto a las fechas, creo que así es como el OP ha elegido especificarlas en su entorno.
Andriy M
"las uniones explícitas ... tienen prioridad sobre las implícitas". ¿Puede proporcionar una cita para esto, por favor? por ejemplo, ¿está definido en los Estándares SQL o es una característica del producto? Gracias.
cuando el
1
@onedaywhen: Me temo que esto no es más que una observación de mi parte hasta ahora. Me siento un tanto aliviado por el hecho de que no soy el primero en hablar sobre la precedencia de las uniones aquí, pero aparte de eso, me gustaría encontrar cualquier tipo de confirmación oficial.
Andriy M
1
En mi caso, olvidé poner espacios cuando concatenaba cadenas para construir el sql, por lo que 'FROM dbo.table_a a' + 'INNER JOIN dbo.table_b b' se convirtió en 'FROM dbo.table_a aINNER JOIN dbo.table_b b', y se confundió y me dio este mensaje de error. Detalles, detalles, detalles.
Guy Schalnat
40

A veces, este error ocurre cuando usa su esquema (dbo) en su consulta de manera incorrecta.

por ejemplo si escribes:

select dbo.prd.name
from dbo.product prd

Obtendrás el error.

En estas situaciones cámbielo a:

select prd.name
from dbo.product prd
Bobs
fuente
1
Esta es bastante molesta y me llevó demasiado tiempo darme cuenta. Gracias La parte más molesta es que a veces se queja de esto, pero otras veces pasa de manera
normal
12

si le ha dado un nombre alies, cámbielo a nombre real

por ejemplo

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;

cambiar eso a

SELECT  
    A.name,A.date
  FROM [LoginInfo].[dbo].[TableA] as A
   join 
  [LoginInfo].[dbo].[TableA] as B 
  on  A.name=B.name;
Alexander Zaldostanov
fuente
1
Además, si está construyendo la cadena sql, tenga cuidado con la falta de espacios finales al final de la línea. Convirtió mi alias M en MINNER cuando se unió a la siguiente línea INNER JOIN a continuación. El generador de perfiles SQL que muestra la cadena ejecutada ayudó a resolver mi problema. (Comentado aquí ya que está relacionado con el alias v problema del nombre real)
Simon
wow @ Simon, gracias. Ni siquiera pensé en esto y estaba golpeando mi cabeza contra la pared tratando de entender por qué mi consulta no funcionaba, ¡me faltaba un espacio al final de uno de los retornos del carro de cuerda!
buradd
9

Estaba luchando con el mismo mensaje de error en SQL SERVER, ya que tenía varias combinaciones, cambiar el orden de las combinaciones lo resolvió para mí.

Pavel M.
fuente
3

En mi caso, el problema resultó ser el nombre de alias que le había dado a la tabla. "oa" parece no ser aceptable para SQL Server.

Hashim Akhtar
fuente
2

Estaba teniendo el mismo error de JDBC. Revisé todo y mi consulta estuvo bien. Resultó, en donde cláusula tengo un argumento:

where s.some_column = ?

Y el valor del argumento que estaba transmitiendo era nulo. Esto también da el mismo error que es engañoso porque cuando buscas en Internet terminas diciendo que algo anda mal con la estructura de la consulta, pero no es mi caso. Solo pensé que alguien podría enfrentar el mismo problema

xbmono
fuente
2

Lo que funcionó para mí fue cambiar mi cláusula WHERE en una subconsulta SELECT

DE:

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

A:

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

Soy nuevo en SQL, pero me encontré con este problema en un curso que estaba tomando y descubrí que asignar la consulta al proyecto específicamente ayudó a eliminar el error de varias partes. Por ejemplo, el proyecto que creé fue CTU SQL Project, así que me aseguré de comenzar mi script con USE [CTU SQL Project] como mi primera línea como se muestra a continuación.

USE [CTU SQL Project]
SELECT Advisors.First_Name, Advisors.Last_Name...and so on.
Bogartz
fuente
1
Cuando dices "proyecto" supongo que te refieres a la base de datos y no a la proyección. La declaración de uso simplemente cambia a qué base de datos está buscando la consulta
Charleh
Sí, proyecto Charleh como en la base de datos en la que estaba trabajando. No estaba seguro de lo que estaba haciendo mal con mi base de datos, pero al indicar "uso" y la base de datos específica al alcance eliminó mi error.
Bogartz
1

Si este error ocurre en un UPDATE , verifique dos vecesJOIN en la tabla con la columna / campo que está causando el error.

En mi caso, esto se debió a la falta de JOINsí mismo, que generó el mismo error debido a un campo desconocido (como señaló Andriy ).

CPHPython
fuente
1

En su lugar, puede intentar unir tablas como,

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

Esto debería funcionar

Suman Kumar
fuente
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
fuente
Utilice los nombres de las tablas en lugar de utilizar un alias si surge un problema de enlace de varias partes.
SVaidya
1

Mi error fue utilizar un campo que no existía en la tabla.

table1.field1 => no existe

table2.field1 => es correcto

Corrija el nombre de su tabla.

mi error ocurrió por usar WITH

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

cuando se usa en combinación con otras tablas ...

Zolfaghari
fuente
1

¿Olvidaste unirte a algunas mesas? Si no, entonces probablemente necesites usar algunos alias.

Tadej
fuente
1

También estaba luchando con este error y terminé con la misma estrategia que la respuesta. Incluyo mi respuesta solo para confirmar que esta es una estrategia que debería funcionar.

Aquí hay un ejemplo en el que primero hago una unión interna entre dos tablas que sé que obtuvieron datos y luego dos uniones externas izquierdas en las tablas que pueden tener filas correspondientes que pueden estar vacías. Combina combinaciones internas y combinaciones externas para obtener resultados con datos entre tablas en lugar de hacer la sintaxis separada por comas predeterminada entre tablas y omitir filas en la combinación deseada.

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

Primero: realice las uniones internas entre las tablas que espera que coincidan con los datos. Segunda parte: continúe con las uniones externas para intentar recuperar datos en otras tablas, pero esto no filtrará su conjunto de resultados si la unión externa de la tabla no tiene los datos correspondientes o coincide con la condición que configuró en el predicado / condición.

Tore Aurstad
fuente
0

Este error también puede ser causado simplemente por faltar una coma , entre los nombres de columna en la instrucción SELECT.

p.ej:

SELECT MyCol1, MyCol2 MyCol3 FROM SomeTable;
Andrés
fuente