Проблема внешнего соединения в SQL Server - PullRequest
0 голосов
/ 28 августа 2009

Это мой запрос. И я хочу, чтобы все строки BF и соответствующие строки FT. Он возвращает только 2 строки, но реальное количество строк составляет 135. Как мне изменить мой запрос?

SELECT 
  BF.FaturaNo,
  K.KlinikAdi,
  FT.teslimAlindi,
  FT.TeslimAciklama,
  FT.kurumTeslimAldi,
  FT.kurumTeslimAciklama,
  BF.basilmisFatura_id,
  K.klinik_id
FROM 
  BasilmisFaturalar AS BF
LEFT OUTER JOIN 
  FaturaTeslim AS FT 
  ON FT.refBasilmisFatura_id = BF.BasilmisFatura_id
INNER JOIN 
  Klinikler AS K 
  ON BF.refKlinik_id = K.klinik_id
INNER JOIN 
  Faturalar AS F 
  ON F.refBasilmisFatura_id = BF.basilmisFatura_id
WHERE 
      BF.FaturaNo LIKE '%%'
  AND BF.refklinik_id IN ('24','25','26','27')
  AND MONTH(F.faturaTarihi) = 7 
  AND teslimAlindi = 0 
  AND kurumTeslimAldi = 0
GROUP BY 
  F.refBasilmisFatura_id,
  BF.FaturaNo,
  K.KlinikAdi,
  FT.teslimAlindi,
  FT.TeslimAciklama,
  FT.kurumTeslimAldi,
  FT.kurumTeslimAciklama,
  BF.basilmisFatura_id,
  K.klinik_id
ORDER BY
  faturaNo ASC

Ответы [ 4 ]

2 голосов
/ 28 августа 2009

Предложение WHERE имеет

 AND teslimAlindi = 0  
 AND kurumTeslimAldi = 0  

Предполагая, что эти необъявленные столбцы взяты из таблицы FaturaTeslim, вы фактически говорите:
- Получить все нужные строки из BasilmisFaturalar
- Сопоставьте их с любыми строками, найденными в FaturaTeslim, но это нормально, если ни один не найден
- И из этих результатов отбросьте все строки, где teslimAlindi <> 0 или kurumTeslimAldi <> 0

С левым внешним объединением для тех строк, в которых совпадения не найдены в FaturaTeslim, teslimAlindi и kurumTeslimAldi, будут иметь значение NULL, и это приведет к их удалению предложением where (поскольку они не = 0).

Фрагмент кода gbn показывает, как это исправить, проверяя эти значения в предложении ON внешнего соединения - что работает, ЕСЛИ это бизнес-логика, которую вы хотите реализовать (то есть только LOJ для тех строк FaturaTeslim, где teslimAlindi = 0 и kurumTeslimAldi = 0

2 голосов
/ 28 августа 2009

Ваши фильтры teslimAlindi и kurumTeslimAldi находятся на стороне "OUTER", поэтому этот BF присоединяется к INNER JOIN.

Сначала необходимо выполнить фильтрацию перед объединением или выполнить фильтрацию в предложении ON. Я предпочитаю этот подход производной таблицы

    ....
FROM BasilmisFaturalar AS BF
    LEFT OUTER JOIN
    (SELECT *
    FROM
        FaturaTeslim
    WHERE
        teslimAlindi = 0 AND 
        kurumTeslimAldi = 0
    )  AS FT ON FT.refBasilmisFatura_id = BF.BasilmisFatura_id
    INNER JOIN Klinikler AS K ON BF.refKlinik_id = K.klinik_id
    INNER JOIN Faturalar AS F ON F.refBasilmisFatura_id = BF.basilmisFatura_id
WHERE BF.FaturaNo LIKE '%%' AND 
    BF.refklinik_id IN ('24','25','26','27') AND 
    MONTH(F.faturaTarihi) = 7 
2 голосов
/ 28 августа 2009

В вашем предложении where есть teslimAllindi и kurumTeslimAldi.

Соединение выполняется перед предложением where. Таким образом, для каждой строки, где нет записи FakturaTeslim, TeslimAllindi и KurumTeslimAldi будут NULL после объединения.

Эти строки будут отфильтрованы предложением where, в результате чего левое соединение будет работать как внутреннее соединение.

Вы должны написать это вместо:

SELECT 
  BF.FaturaNo,
  K.KlinikAdi,
  FT.teslimAlindi,
  FT.TeslimAciklama,
  FT.kurumTeslimAldi,
  FT.kurumTeslimAciklama,
  BF.basilmisFatura_id,
  K.klinik_id
FROM 
  BasilmisFaturalar AS BF
LEFT OUTER JOIN 
  FaturaTeslim AS FT 
  ON 
    (FT.refBasilmisFatura_id = BF.BasilmisFatura_id
     AND teslimAlindi = 0 
     AND kurumTeslimAldi = 0)
INNER JOIN 
  Klinikler AS K 
  ON BF.refKlinik_id = K.klinik_id
INNER JOIN 
  Faturalar AS F 
  ON F.refBasilmisFatura_id = BF.basilmisFatura_id
WHERE 
      BF.FaturaNo LIKE '%%'
  AND BF.refklinik_id IN ('24','25','26','27')
  AND MONTH(F.faturaTarihi) = 7 
GROUP BY 
  F.refBasilmisFatura_id,
  BF.FaturaNo,
  K.KlinikAdi,
  FT.teslimAlindi,
  FT.TeslimAciklama,
  FT.kurumTeslimAldi,
  FT.kurumTeslimAciklama,
  BF.basilmisFatura_id,
  K.klinik_id
ORDER BY
  faturaNo ASC
0 голосов
/ 28 августа 2009

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

Кроме того, BF.FaturaNo LIKE '%%', вероятно, следует заменить на более понятный BF.FaturaNo IS NOT NULL

Попробуйте свести свою проблему к более простой демонстрации концепции. У вас слишком много материала для конкретной модели данных, встроенного в этот вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...