Как получить конкретную запись из таблицы X, соединяющей таблицу Y или таблицу Z, где таблицы Y и Z имеют одинаковое имя столбца с одинаковыми данными?

У меня есть запрос ниже, где я получаю данные из журнала объединения таблиц и оборудования, но b.id, который выходит из оборудования таблицы, также находится в другой таблице с именем Equipment2 с тем же именем столбца. поэтому мне нужно написать запрос, в котором, если таблица оборудования имеет пустое или нулевое значение в этом столбце идентификатора, тогда я должен вытащить запись, объединяющую таблицу оборудования2 с журналом таблицы, в противном случае она должна присоединиться к оборудованию таблицы и журналу.

SELECT TO_CHAR (a.LOG_DATE, 'mm/dd/yyyy HH:MI:SS') LOG_DATE,
b.id,
a.atid,
a.l_type,
a.l_subtype,
a.eq,
a.name,
a.comments
FROM log a, (equipment b or equipment2 b)
WHERE a.eqid = b.eqid(+)
AND log_date BETWEEN TO_DATE ('07/01/2013', 'MM/DD/YYYY')
                      AND  TO_DATE ('07/08/2070', 'MM/DD/YYYY')
GROUP BY a.log_date,
b.id,
a.atid,
a.l_type,
a.l_subtype,
a.eq,
a.name,
a.comments
ORDER BY b.id;

person user2528510    schedule 09.07.2013    source источник
comment
Определена ли какая-либо ссылка между этими таблицами? Мне эта фраза кажется странной: equipment table has **empty** or null value. Кроме того, почему две таблицы снаряжения? Имеют ли они одинаковую структуру?   -  person Eggplant    schedule 09.07.2013
comment
у нас есть два типа оборудования в нашей базе данных. скажем, когда пользователь отправляет свой запрос, он может выбрать оборудование типа 1 или типа 2. Данные обоих типов оборудования поступают из одной таблицы, называемой eqdata, где идентификатор (первичный ключ) один и тот же, но тип оборудования другой. поэтому мы хранили данные в зависимости от типа оборудования. если его тип оборудования 1, то он попадет в таблицу оборудования 1, иначе, если его тип оборудования 2, он перейдет в таблицу оборудования 2.   -  person user2528510    schedule 09.07.2013
comment
Таких проблем становится намного легче избежать или решить с помощью синтаксиса ANSI-92.   -  person Wolf    schedule 09.07.2013


Ответы (2)


Предполагая, что дочерняя запись ВСЕГДА будет либо в оборудовании, либо в оборудовании2, но никогда не в обоих, вы можете просто добавить оборудование2 с внешним соединением и использовать NVL() для выбора ненулевого значения:

SELECT TO_CHAR (a.LOG_DATE, 'mm/dd/yyyy HH:MI:SS') LOG_DATE,
  nvl(b.id,b2.id),
  a.atid,
  a.l_type,
  a.l_subtype,
  a.eq,
  a.name,
  a.comments
FROM 
  log a, 
  equipment b,
  equipment2 b2
WHERE 
  a.eqid = b.eqid(+)
  AND a.eqid = b2.eqid(+)
  AND log_date BETWEEN TO_DATE ('07/01/2013', 'MM/DD/YYYY')
                  AND  TO_DATE ('07/08/2070', 'MM/DD/YYYY')
ORDER BY 2

Это также предполагает, что вы выбираете только столбец, который не будет заполнен NULL. Если, например, оборудование/оборудование2 также содержит столбец «имя», который может быть нулевым, вам потребуется дополнительная логика:

case when b.id is null then b2.name else b.name end
person Joe    schedule 09.07.2013

Другая возможность состоит в том, чтобы объединить две таблицы оборудования и просто соединить их. Предполагая, что структура таблицы идентична для оборудования и оборудования2, в противном случае вы, конечно, захотите выбрать свои конкретные поля. В противном случае...

 SELECT *
 INTO #equipTemp
 FROM equipment WHERE ID IS NOT NULL
 UNION ALL
 SELECT * FROM equipment2 WHERE ID IS NOT NULL

SELECT TO_CHAR (a.LOG_DATE, 'mm/dd/yyyy HH:MI:SS') LOG_DATE,
 b.id,
 a.atid,
 a.l_type,
 a.l_subtype,
 a.eq,
 a.name,
 a.comments
 FROM log a, #eqipTemp b
 WHERE a.eqid = b.eqid(+)
 AND log_date BETWEEN TO_DATE ('07/01/2013', 'MM/DD/YYYY')
                  AND  TO_DATE ('07/08/2070', 'MM/DD/YYYY')
 GROPU BY...
person R_Scott    schedule 09.07.2013