una right length hasta extraer ejemplos charindex caracteres caracter cadena buscar sql-server outer-join

sql server - right - Top 1 con una combinación izquierda



sql substring hasta un caracter (4)

Dada la siguiente consulta, puede haber varias filas en dps_markers con la misma clave de marcador, pero solo queremos unirnos contra la primera. Si tomo esta consulta y elimino el top 1 y ORDER BY obtengo un valor para mbg.marker_value pero lo ejecuto como está, siempre devuelve null

SELECT u.id, mbg.marker_value FROM dps_user u LEFT JOIN (SELECT TOP 1 m.marker_value, um.profile_id FROM dps_usr_markers um (NOLOCK) INNER JOIN dps_markers m (NOLOCK) ON m.marker_id= um.marker_id AND m.marker_key = ''moneyBackGuaranteeLength'' ORDER BY m.creation_date ) MBG ON MBG.profile_id=u.id WHERE u.id = ''u162231993''


Damir está en lo correcto,

Su subconsulta necesita asegurarse de que dps_user.id sea igual a um.profile_id, de lo contrario tomará la fila superior que podría, pero probablemente no será igual a su id de ''u162231993''

Su consulta debería verse así:

SELECT u.id, mbg.marker_value FROM dps_user u LEFT JOIN (SELECT TOP 1 m.marker_value, um.profile_id FROM dps_usr_markers um (NOLOCK) INNER JOIN dps_markers m (NOLOCK) ON m.marker_id= um.marker_id AND m.marker_key = ''moneyBackGuaranteeLength'' WHERE u.id = um.profile_id ORDER BY m.creation_date ) MBG ON MBG.profile_id=u.id WHERE u.id = ''u162231993''


La clave para depurar situaciones como esta es ejecutar la subconsulta / vista en línea para ver cuál es el resultado:

SELECT TOP 1 dm.marker_value, dum.profile_id FROM DPS_USR_MARKERS dum (NOLOCK) JOIN DPS_MARKERS dm (NOLOCK) ON dm.marker_id= dum.marker_id AND dm.marker_key = ''moneyBackGuaranteeLength'' ORDER BY dm.creation_date

Al ejecutar eso, vería que el valor de u162231993 no coincide con el valor de u162231993 de u162231993 , lo que explicaría por qué cualquier referencia de mbg devolvería null (gracias a la combinación de la izquierda; no obtendría nada si fuera un interno unirse).

Te has codificado en una esquina usando TOP , porque ahora tienes que modificar la consulta si deseas ejecutarla para otros usuarios. Un mejor enfoque sería:

SELECT u.id, x.marker_value FROM DPS_USER u LEFT JOIN (SELECT dum.profile_id, dm.marker_value, dm.creation_date FROM DPS_USR_MARKERS dum (NOLOCK) JOIN DPS_MARKERS dm (NOLOCK) ON dm.marker_id= dum.marker_id AND dm.marker_key = ''moneyBackGuaranteeLength'' ) x ON x.profile_id = u.id JOIN (SELECT dum.profile_id, MAX(dm.creation_date) ''max_create_date'' FROM DPS_USR_MARKERS dum (NOLOCK) JOIN DPS_MARKERS dm (NOLOCK) ON dm.marker_id= dum.marker_id AND dm.marker_key = ''moneyBackGuaranteeLength'' GROUP BY dum.profile_id) y ON y.profile_id = x.profile_id AND y.max_create_date = x.creation_date WHERE u.id = ''u162231993''

Con eso, puede cambiar el valor de id en la cláusula where para verificar los registros de cualquier usuario en el sistema.


Porque el TOP 1 de la profile_id = ''u162231993'' ordenada no tiene profile_id = ''u162231993'' Quite where u.id = ''u162231993'' y vea los resultados.

Ejecute la subconsulta por separado para comprender qué está pasando.


Utilice APLICACIÓN EXTERIOR en lugar de APUESTA IZQUIERDA:

SELECT u.id, mbg.marker_value FROM dps_user u OUTER APPLY (SELECT TOP 1 m.marker_value, um.profile_id FROM dps_usr_markers um (NOLOCK) INNER JOIN dps_markers m (NOLOCK) ON m.marker_id= um.marker_id AND m.marker_key = ''moneyBackGuaranteeLength'' WHERE um.profile_id=u.id ORDER BY m.creation_date ) AS MBG WHERE u.id = ''u162231993'';

A diferencia de JOIN, APPLY le permite hacer referencia al u.id dentro de la consulta interna.