簡體   English   中英

OracleSQL:如何向查詢添加特定的AND不為null或不為null

[英]OracleSQL: How do I add a specific AND is not null OR is not null to my query

背景故事

  • 我有三個正在使用的桌子。 目錄表(目錄),常規屬性表(attribute1table)和特定屬性表(attribute2table)。 常規屬性表在屬性ID的屬性(attrid = 2)下保存屬性名稱(例如姓氏)。 特定屬性表包含這些屬性(例如Doe)的特定數據。
  • 我需要將行轉置為列。 我之前曾嘗試使用數據透視和max(decode),但是所有選項給我的字符串值都不正確-因此我在select語句中使用了子選擇。 效果很好-確實將行轉置為列,但給了我一堆空值。 請參閱底部的查詢以獲取步驟。
  • 然后,我添加了一個通用的“ stringval IS NOT NULL”以消除其他任何attribute1table.attrid的屬性(例如4、5、6)。 這工作了。

這是我此時得到的輸出。 為空值。

Name    DataID    LastName    FirstName
File10  1290      ?           Jane
File10  1290      Doe         ?
  • 然后,我想添加一個規范。 本質上包括LastName不為null或FirstName不為null的值。 我發現有人建議在上一個問題中這樣做,盡管他們的情況有所不同。 在sql select中消除特定的null值

我能夠包含一個或另一個語句,但不能同時添加兩個。 我沒有得到任何錯誤,而只是獲得了令人難以置信的長運行時間,沒有可預見的結果(請注意,我正在使用允許您在界面內輸入oracle查詢以查詢數據庫的軟件)。 如果我一直運行查詢直到**(請參見代碼),它就會起作用,但是一旦我添加OR條件,它就不再起作用。 我認為這是因為我有多個WHERE條件。 在所有情況下,我都希望應用目錄ID和一般stringval條件,但是我想擁有第三個條件,即姓氏不為null或名字不為null。 我不確定是否缺少明顯的東西-請幫忙嗎?

這是我當前的查詢:

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**

基本上,我只需要擺脫null值,並希望我的表看起來像...。

Name      DataID    LastName    FirstName
File10    1290      Doe         Jane

這似乎是一個括號問題。 如果我理解此問題,則需要將兩個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)

我還使用聯接而不是子選擇重寫了查詢,因為我認為這更清楚了。

還要注意,在M2M3聯接中,我使用條件為1 = 1 LEFT OUTER而不是CROSS JOIN ,因為我注意到,如果交叉INNER JOIN的查詢不返回任何行,則CROSS JOIN作用類似於INNER JOIN也就是說,它導致整個SELECT不返回任何數據。 dbfiddle在這里演示這種情況

我很確定您只需要條件聚合:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM