Дополнительные пустые строки при использовании LEFT OUTER JOIN - PullRequest
0 голосов
/ 19 июня 2020

У меня есть три таблицы SpringCount, SpringObservation и MonitoringPoint. SpringCount и SpringObservation участвуют в отношениях "один ко многим". В некоторых учетах нет наблюдения за птицами, в некоторых - нет. Я хочу вернуть таблицу со всеми представленными счетчиками и значениями NULL в соответствующих полях, если у них нет соответствующего наблюдения. Я понимаю, что при выполнении левого внешнего соединения это приведет к появлению повторяющихся строк, и это то, что я хочу, однако я получаю как нужные повторяющиеся строки, так и повторяющиеся строки, полные нулей, которые, по моему мнению, не должны быть там. Я не уверен, где в моем запросе я ошибаюсь.

MonitoringPoint Table
MonitoringPoint  |  StateID
       1A              DE
       2A              DE
       3A              DE
       4A              DE
       5B              GA
       67C             IL

SpringCount Table
MonitoringPoint | CountID   |  Temp  |  Clouds  |
       1A            1          70        50
       2A            2          60        30
       3A            3          40        20
       4A            4          80        10

Spring Observation Table
SpringObsvID  |   CountID   |   Species
     A               1           NOBO
     B               3           FISP
     C               3           FISP
     D               3           NOBO
     E               4           PRAW
     F               4           FISP

Это код, который я выполняю (просто верьте, что все поле GDB_TO_DATE существует и не равно нулю для всех записей, даже если оно не в приведенных выше примерах таблиц)

SELECT 
      sc.CountID
      ,[Temperature]
      ,[CloudCover]
      ,so.Species
  FROM [CollectorSpatialData].[dbo].[SPRINGCOUNT] sc
  JOIN MONITORINGPOINT mp
  ON sc.MonitoringPointID = mp.MonitoringPointID
    and StateID = 'DE'
  LEFT JOIN SPRINGOBSERVATION so
  ON sc.CountID = so.CountID
    and year(sc.GDB_TO_DATE) = 9999
    and year(so.GDB_TO_DATE) = 9999
order by CountDate

Это таблица, которую я ожидаю , чтобы получить

Output Table
    CountID  |   Temperature  |  Clouds  |  Species 
       1            70             50        NOBO
       2            60             30        NULL
       3            40             20        FISP
       3            40             20        FISP
       3            40             20        NOBO
       4            80             10        PRAW
       4            80             10        FISP

Это таблица На самом деле я получаю. Я не уверен, почему CountID перечисляет все совпадения, но также производит (казалось бы) случайное количество несовпадений для того же самого CountID.

Output Table
CountID  |   Temperature  |  Clouds  |  Species 
   1            70             50        NULL 
   1            70             50        NULL 
   1            70             50        NULL 
   1            70             50        NOBO
   2            60             30        NULL
   2            60             30        NULL
   2            60             30        NULL
   2            60             30        NULL
   3            40             20        NULL
   3            40             20        NULL
   3            40             20        NULL
   3            40             20        FISP
   3            40             20        FISP
   3            40             20        NOBO
   4            80             10        NULL
   4            80             10        NULL
   4            80             10        NULL
   4            80             10        PRAW
   4            80             10        FISP

Есть ли в моем запросе что-то, что нужно изменить, или я ошибаюсь, думая о том, как работают левые внешние соединения? Я использовал SELECT DISTINCT, и это, по крайней мере, группирует все эти ошибочные строки с нулевым значением вместе, что помогает, но они все еще существуют, и я не уверен, почему.

1 Ответ

0 голосов
/ 19 июня 2020

Спасибо @underscore_d за то, что он помог мне получить ответ. Мне нужно было посмотреть на поля, которые не были частью моего запроса, чтобы понять, что происходит. Оказалось, что мне нужно было выполнить подзапрос, потому что поля GDB_TO_DATE в каждой таблице действовали неожиданным образом. Что мне нужно, так это все счета, которые заканчиваются на 9999 год, чтобы соответствовать любому из наблюдений, закончившихся в 9999 году. Все, что не заканчивается на 9999 год, является исторической / архивной записью, но хранится в той же таблице, что и текущие записи (это пространственная база данных и программное обеспечение, которое их создает, делает их такими, определенно не мой выбор) . Из-за того, что архивные и текущие записи расположены в одной таблице, просто использовать идентификаторы подсчета для сопоставления записей недостаточно, потому что вы в конечном итоге сопоставите текущий счетчик с заархивированным наблюдением, у которого все еще есть этот идентификатор. Мне нужно было выбрать все текущие наблюдения, прежде чем пытаться присоединиться к текущим счетчикам, чтобы архивные наблюдения не были включены в объединение.

Вот окончательный код:

SELECT 
      sc.CountID
      ,[Temperature]
      ,[CloudCover]
      ,sub.Species
  FROM [CollectorSpatialData].[dbo].[SPRINGCOUNT] sc
  JOIN MONITORINGPOINT mp
  ON sc.MonitoringPointID = mp.MonitoringPointID
    and StateID = 'DE'
  LEFT JOIN 
    (SELECT so.CountID, 
            so.Species
     FROM SPRINGOBSERVATION so
     WHERE year(so.GDB_TO_DATE) = 9999) AS sub
  ON sc.GlobalID = sub.CountID
  where year(sc.GDB_TO_DATE) = 9999
order by CountDate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...