Лучший 1 с левым соединением

Учитывая запрос ниже могло бы быть несколько строк в dps_markers с тем же ключом маркера, но мы только хотим присоединиться против первого. Если я беру этот запрос и удаляю лучший 1 и ORDER BY, я получаю значение для mbg.marker_value, но работаю, поскольку это - это, всегда возвращает пустой указатель

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'
84
задан dstarh 2 July 2014 в 17:06
поделиться

4 ответа

Использовать ВНЕШЕЕ ПРИЛОЖЕНИЕ вместо ЛЕВОГО JOIN:

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';

В отличие от JOIN, APPLY позволяет ссылаться на u.id внутри внутреннего запроса.

182
ответ дан 24 November 2019 в 08:32
поделиться

Дамир прав,

Ваш подзапрос должен гарантировать, что 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'
0
ответ дан 24 November 2019 в 08:32
поделиться

Поскольку TOP 1 из упорядоченного подзапроса не имеет profile_id = 'u162231993' Удалите , где u.id = 'u162231993' , и затем просмотрите результаты.

Выполните подзапрос отдельно, чтобы понять, что происходит.

1
ответ дан 24 November 2019 в 08:32
поделиться

Ключ для отладки ситуаций, подобных этим, состоит в том, чтобы запускать подзаконный / встроенный вид на его «собственно, чтобы увидеть, какой вывод:

  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 значение U162231956] U162231953 , что объяснило бы, почему любой MBG ссылки вернутся NULL (Благодаря левому соединению; вы не получите ничего, если бы это было внутренним соединением).

Вы закодировали себя в угол, используя верхнюю часть , потому что теперь вы должны настроить запрос, если вы хотите запустить его для других пользователей. Лучший подход будет:

   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 в , где , где , где , чтобы проверить записи для любого пользователя в системе.

2
ответ дан 24 November 2019 в 08:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: