OracleSQL: как добавить конкретное И не является нулевым ИЛИ не является нулевым в моем запросе - PullRequest
0 голосов
/ 19 января 2019

Предыстория :

  • У меня есть три стола, с которыми я работаю. Таблица каталогов (каталог), таблица общих атрибутов (attribute1table) и таблица конкретных атрибутов (attribute2table). Общие таблицы атрибутов содержат имена атрибутов (например, Фамилия) под идентификаторами атрибутов (attrid = 2). Таблица конкретных атрибутов содержит конкретные данные для этих атрибутов (например, Доу).
  • Мне нужно было транспонировать строки в столбцы. Я пытался использовать pivot и max (decode) раньше, но все опции дали мне неверное строковое значение - поэтому я использовал подвыбор внутри оператора select. Это сработало хорошо - оно транспонировало строки в столбцы, но дало мне кучу нулевых значений. Смотри запрос внизу для шагов.
  • Затем я добавил общее 'stringval IS NOT NULL', чтобы исключить любые другие атрибуты attribute1table.attrid (например, 4, 5, 6). Это сработало.

Это вывод, который я получил в этот момент. ? являются нулевыми значениями.

Name    DataID    LastName    FirstName
File10  1290      ?           Jane
File10  1290      Doe         ?
  • Тогда я хотел добавить в спецификацию. По сути, чтобы включить значения, где LastName не является нулевым ИЛИ FirstName не является нулевым. Я обнаружил, что кто-то рекомендовал сделать это в предыдущем вопросе, хотя их ситуация отличалась. Устранение определенных нулевых значений в sql select

Я смог включить одно или другое утверждение, но не смог добавить оба. Вместо того, чтобы получить ошибку, я получил ужасно длительное время выполнения без ожидаемого результата (обратите внимание, что я использую программное обеспечение, которое позволяет вводить запросы оракула в интерфейсе для запроса к базе данных). Это работает, если я запускаю запрос до ** (см. Код), но как только я добавляю в условие OR, он больше не работает. Я думаю, это потому, что у меня есть несколько условий ГДЕ. Во всех случаях я хочу, чтобы применялись идентификатор каталога и общие строковые условия, но я хочу иметь третье условие, где либо фамилия не равна нулю, либо имя не равно нулю. Я не уверен, что упускаю что-то очевидное - помогите, пожалуйста?

Вот мой текущий запрос:

SELECT directory.name, directory.dataid,
(SELECT max(stringval) FROM attribute2table WHERE attribute1table.attrid = 2) as LastName,
(SELECT max(stringval) FROM attribute2table WHERE attribute1table.attrid = 3) as FirstName

FROM attribute2table
JOIN directory ON directory.dataid = attribute2table.id
JOIN attribute1table ON attribute1table.id = directory.dataid
WHERE directory.dataid = 1290
AND stringval IS NOT NULL
AND (SELECT max(valstr) FROM attribute1table WHERE attribute1table.attrid = 2) IS NOT NULL
**OR (SELECT max(valstr) FROM attribute1table WHERE attribute1table.attrid = 3) IS NOT NULL**

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

Name      DataID    LastName    FirstName
File10    1290      Doe         Jane

Ответы [ 2 ]

0 голосов
/ 19 января 2019

Похоже, это проблема с круглыми скобками. Если я понимаю проблему, вам нужно поместить в скобки два условия IS NOT NULL:

SELECT directory.name,
       directory.dataid, 
       m2.LastName, 
       m3.FirstName
  FROM attribute2table
  INNER JOIN directory
    ON directory.dataid = attribute2table.id
  INNER JOIN attribute1table
    ON attribute1table.id = directory.dataid
  LEFT OUTER JOIN (SELECT max(valstr) AS LASTNAME
                     FROM attribute1table
                     WHERE attribute1table.attrid = 2) m2
    ON 1 = 1
  LEFT OUTER JOIN (SELECT max(valstr) AS FIRSTNAME
                     FROM attribute1table
                     WHERE attribute1table.attrid = 3) m3
    ON 1 = 1
  WHERE directory.dataid = 1290 AND
        stringval IS NOT NULL AND
        (m2.LASTNAME IS NOT NULL OR
         m3.FIRSTNAME IS NOT NULL)

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

Обратите внимание, что в соединениях M2 и M3 я использовал LEFT OUTER с условием 1 = 1 вместо использования CROSS JOIN, потому что я заметил, что CROSS JOIN действует как INNER JOIN если перекрестный запрос не возвращает строк, то есть весь SELECT не возвращает данных. dbfiddle демонстрирует эту ситуацию здесь

0 голосов
/ 19 января 2019

Я почти уверен, что вам нужно только условное агрегирование:

SELECT d.name, d.dataid,
       MAX(CASE WHEN a1.attrid = 2 THEN a2.stringval END) as LastName,
       MAX(CASE WHEN a1.attrid = 3 THEN a2.stringval END) as FirstName
FROM directory d JOIN
     attribute2table a2
     ON a2.id = d.dataid JOIN
     attribute1table a1
     ON a1.id = d.dataid
WHERE d.dataid = 1290
GROUP BY d.name, d.dataid
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...