Чем объединение с подзапросом отличается от присоединения без подзапроса?Ищем разницу между двумя похожими запросами - PullRequest
0 голосов
/ 04 июня 2019

Я хочу посмотреть, какой пользователь создал оборудование для пола, для какого клиента - оба эти запроса выполняют то, что я хочу. Второй запрос, однако, приводит на 700 строк больше, чем первый. Не могли бы вы объяснить разницу?

Я запустил другой запрос, который обнаружил разницу между двумя наборами - конечно же, этот запрос дал 700 строк. Поэтому вывод данных такой же, но второй запрос каким-то образом ловит больше результатов. Я попытался посмотреть на дополнительные 700 строк, но все они казались нормальными и похожими на другие результаты. Я не могу найти разницу, глядя на код, и я надеюсь, что кто-то может помочь мне с

Первый запрос

SELECT customer.name, user.name, floor_equipment.id
FROM customer, user, floor_equipment, floor, building, site
WHERE (floor_equipment.floorID = floor.ID AND floor.buildingID = building.id AND
building.siteID = site.id AND floor_equipment.created_by = user.id)

Второй запрос

SELECT newTable.custName, newTable.userName, newTable.equipID
FROM (SELECT customer.name as "custName", user.name as "userName", 
floor_equipment.id as "equipID", floor_equipment.created_by as "creatorID" 
FROM customer, floor_equipment, floor, building, site 
WHERE (floor_equipment.floorID = floor.ID AND floor.buildingID = building.id AND
building.siteID = site.id AND site.customerID = customer.ID)) as newTable, user 
WHERE user.id = newTable.creatorID

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

ПРИМЕЧАНИЕ. Во втором запросе, казалось бы, бессмысленный подзапрос. Целью этого была оптимизация. Я выполняю эти запросы в Domo, веб-приложении для бизнес-аналитики. Я написал подзапрос в надежде, что он будет работать быстрее. Из-за того, как работает Domo, первый занял 2 часа, а второй - 45 секунд.

Ответы [ 2 ]

0 голосов
/ 04 июня 2019

Ваш код является декартовым произведением между таблицами:

   customer, user, floor_equipment, floor, building, site   

и вашим условием не для соединения, а только для кортежа с логическим значением

 floor_equipment.floorID = floor.ID,    
    floor.buildingID = building.id,
      building.siteID = site.id, 
      floor_equipment.created_by = user.id 

      ( boolean,  boolean, boolean, boolean)  

для каждого логического значенияявляется результатом соответствующего совпадения, например:

          floor_equipment.floorID = floor.ID

, поэтому практически верните все строки, потому что не совпадающий аналог

во втором первом декартовом произведении расширяется путем объединения первого результатаи совпадающие строки для user.id и newTable.creatorID
, обращающиеся к вашему коду, могут указывать на то, что вам нужен явный синтаксис объединения и правильное условие

0 голосов
/ 04 июня 2019

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

SELECT c.name
     , u.name
     , fe.id
  FROM customer c
 CROSS 
  JOIN user u
  JOIN floor_equipment fe
    ON fe.created_by = u.id
  JOIN floor f
    ON f.ID = fe.floorID 
  JOIN building b
    ON b.id = f.buildingID 
  JOIN site s
    ON s.id = b.siteID 

Аналогично, если написать немного более согласованно, ваш второй запрос выглядит следующим образом:

SELECT x.custName
     , x.userName
     , x.equipID
  FROM 
     ( SELECT c.name custName
            , u.name userName
            , fe.id equipID
            , fe.created_by creatorID
         FROM customer c
         JOIN site s
           ON s.customerID = c.ID
         JOIN building b
           ON b.siteID = s.id 
         JOIN floor f
           ON f.buildingID = b.id 
         JOIN floor_equipment fe
           ON fe.floorID = f.ID 
      ) x
   JOIN user u
     ON u.id = x.creatorID

Опять же, мы можем опустить подзапрос и написать его таким образом ...

       SELECT c.name custName
            , u.name userName
            , fe.id equipID
            , fe.created_by creatorID
         FROM customer c
         JOIN site s
           ON s.customerID = c.ID
         JOIN building b
           ON b.siteID = s.id 
         JOIN floor f
           ON f.buildingID = b.id 
         JOIN floor_equipment fe
           ON fe.floorID = f.ID 
         JOIN user u
           ON u.id = fe.created_by

... так что мы можем видеть, что первый запрос имел декартово произведение (CROSS JOIN), тогда каквторой запрос не.

...