Подтвердить что ты не робот

Левая внешняя связь не работает?

У меня есть запрос, извлекающий данные из трех таблиц с использованием LEFT OUTER JOIN для обоих соединений. Мне нужен запрос, чтобы возвращать самую большую информацию (Salesrep table), даже если в двух правых таблицах (предписывающих и рецептах, соответственно) нет соответствующих данных. Когда я запускаю этот запрос без параметров даты в предложении WHERE, я получаю ожидаемый доход, но как только я включаю параметры даты, я ничего не получаю, когда нет соответствующих данных для salesrep. Мне нужно хотя бы увидеть столбцы таблицы salesrep, запрошенные в запросе.

Вот запрос... любая помощь ОЧЕНЬ высоко ценится.

SELECT  salesrep.salesrepid as SalesRepID,
        salesrep.fname as SalesrepFName,
        salesrep.lname as SalesRepLName,
        salesrep.fname+' '+salesrep.lname as SalesRepFullName,
        prescriber.dea_no as PDeaNo,
        prescriber.lname+', '+prescriber.fname as DocName,
        CONVERT(VARCHAR(8), prescriptions.filldate, 1) as FillDate,
        prescriptions.drugname as DrugName,
        prescriptions.daysupply as Supply,
        prescriptions.qtydisp as QtyDisp,
        prescriptions.rx_no as Refill,
        prescriptions.copay as Sample,
        ROUND(prescriptions.AgreedToPay-(prescriptions.AgreedToPay*.07),2) as AgreedToPay,
        prescriptions.carrierid as CarrierID
FROM    salesrep
  LEFT OUTER JOIN prescriber on salesrep.salesrepid = prescriber.salesrepid
  LEFT OUTER JOIN prescriptions on prescriber.dea_no = prescriptions.dea_no
  WHERE salesrep.salesrepid = 143 AND
        prescriptions.filldate >= '09-01-12' AND
        prescriptions.filldate <= '09-17-12'
ORDER BY prescriptions.filldate
4b9b3361

Ответ 1

Вы должны переместить ограничения на prescriptions.filldate в условие ON соединения и удалить его из предложения where:

LEFT OUTER JOIN prescriptions ON prescriber.dea_no = prescriptions.dea_no
                             AND prescriptions.filldate >= '09-01-12'
                             AND prescriptions.filldate <= '09-17-12'

В противном случае записи, для которых нет prescriptions, заканчиваются null в prescriptions.filldate, а предложение where отбрасывает их.

Ответ 2

Здесь вы можете найти краткое описание фаз обработки запросов (это распространено для большинства СУБД). Вы узнаете, что для OUTER JOIN:

  • создается первая CARTESIAN JOIN,
  • чем условие ON выполняется в наборе результатов, производящем подмножество строк,
  • после того, как внешние строки добавляются с помощью NULL во внутренней таблице, соединенных столбцами,
  • на этом результате применяется предложение WHERE, выполняющее фильтрацию.

Когда вы помещаете условие в предложение WHERE, которое касается строк внешних таблиц, все они отбрасываются. Вы должны просто поместить это условие в предложение ON, поскольку оно оценивается до добавления внешних строк.

Итак, эти условия:

prescriptions.filldate >= '09-01-12' AND
prescriptions.filldate <= '09-17-12'

следует переместить в предложение ON.

Ответ 3

Это связано с тем, что ваши неравенства prescriptions.filldate отфильтровывают ваши строки salesrep, которые не имеют значения в столбце prescriptions.filldate.

Итак, если есть нулевые значения (без соответствующих данных из правых таблиц), то вся строка, включая данные salesrep, отфильтровывается фильтрами даты, потому что null не попадает между двумя датами.