Учитывая приведенный ниже запрос, в dps_markers может быть несколько строк с одним и тем же ключом маркера, но мы хотим присоединиться только к первой. Если я возьму этот запрос и удалю верхнюю 1 и ORDER BY, я получу значение для mbg.marker_value, но запустив его как есть, он всегда возвращает 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'
sql-server
outer-join
dstarh
источник
источник
Ключом к отладке подобных ситуаций является запуск подзапроса / встроенного представления самостоятельно, чтобы увидеть, каков результат:
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
Запустив это, вы увидите, что
profile_id
значение не соответствуетu.id
значениюu162231993
, что объясняет, почему любыеmbg
ссылки будут возвращатьсяnull
(благодаря левому соединению; вы бы ничего не получили, если бы это было внутреннее соединение).Вы загнали себя в угол с помощью
TOP
, потому что теперь вам нужно настроить запрос, если вы хотите запустить его для других пользователей. Лучшим подходом было бы: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'
При этом вы можете изменить
id
значение вwhere
предложении, чтобы проверять записи для любого пользователя в системе.источник
Потому что
TOP 1
в подзапросе из упорядоченного подзапроса нетprofile_id = 'u162231993'
Удалитьwhere u.id = 'u162231993'
и посмотреть результаты.Выполните подзапрос отдельно, чтобы понять, что происходит.
источник
Дамир прав,
Ваш подзапрос должен гарантировать, что dps_user.id равен um.profile_id, иначе он захватит верхнюю строку, которая может, но, вероятно, не равна вашему идентификатору u162231993.
Ваш запрос должен выглядеть так:
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'
источник
WHERE um.profile_id = 'u162231993'
подзапрос иWHERE mbg.marker_value IS NOT NULL
снаружи.@SearchFor = 'u162231993'
а затем используйте ееWHERE
или опубликуйте некоторые структуры данных и таблиц, чтобы другие люди могли помочь и опробовать ее.