2014-10-01 64 views
0

背景
我寫的大多數腳本搜索缺少數據的記錄。我使用XXXX_APPL_NO(WHERE XXXX_APPL_NO = YYYY_APPL_NO)中的常用值來確保我選擇的數據來自正確的行。
如果人員有多個應用程序,APPL_NO將有多行記錄。
如果XXXX_APPL_NO不等於YYYY_APPL_NO(因爲數據丟失),該腳本將忽略該行。所以我不能使用WHERE XXXX_APPL_NO = YYYY_APPL_NO
我必須把戲它把我想要的數據給我。我相信我已經想出了檢索它的過程,但我不知道如何編寫它!Oracle SQL - 比較列 - 對於不匹配的值的SELECT記錄

這裏是實際數據。注:我不知道什麼是在空白的領域。約束是「NOT NULL」,所以我相信那裏有東西,我只是不知道它是什麼! Actual Data with Data Types and Constraints

這裏是我當前的代碼:

Select distinct 
sp.spriden_id as "ID", 
SP.SPRIDEN_LAST_NAME as "Last", 
SP.SPRIDEN_FIRST_NAME as "First", 
SA.SARADAP_TERM_CODE_ENTRY as "App Term", 
SA.SARADAP_ADMT_CODE as "Adm Type", 
st.SARAATT_TERM_CODE, 
st.SARAATT_APPL_NO, 
sa.SARADAP_APPL_NO 
/* I want to make a column in my report ONLY - NOT IN THE DATABASE - 
to print out "No WSP" if there is no corresponding SARAATT_APPL_NO 
for the SARADAP_APPL_NO */ 

FROM 
SPRIDEN SP 
JOIN SARADAP SA 
on sp.spriden_pidm = sa.saradap_PIDM 
JOIN SORLCUR SR 
on sp.spriden_pidm = SR.SORLCUR_PIDM 
full outer JOIN SARAATT ST 
on sp.spriden_pidm = ST.SARAATT_PIDM 

Where 
Sp.spriden_change_ind is null 
AND 
SA.SARADAP_ADMT_CODE in ('SP', 'XT') 

這是我當前的代碼返回的數據。請注意,Term_Codes和Appl_Nos不匹配: Data - No app number match condition

請注意:如果我添加st.SARAATT_APPL_NO = sa.SARADAP_APPL_NO WHERE子句,它會跳過所有行與丟失的數據! (我需要所有的的數據,所以我可以除掉我不需要的)
這是返回的數據,如果我加st.SARAATT_APPL_NO = sa.SARADAP_APPL_NOData - with app number condition

爲了找回我需要的數據,我想要做這樣的事情:
從目前的SELECT語句選擇所有的數據。
然後,對於每個SARADAP_APPL_NO,在SARAATT_APPL_NO中找到它的匹配項。
SELECT那些沒有匹配的行,並在我爲報表創建JUST(不在數據庫中)的列中打印「No WSP」。
這是我的意思是什麼「它有一個匹配?」: Does it have a match?

或者我可以做某種
SARADAP_APPL_NO not in (SARAATT_APPL_NO)一定spriden_id?
3 4 not in (2 3 4 5)
如果任何SARAATT_AAPL_NO值(2 3 4 5)的未在SARADAP_APPL_NO值(3 4)包括,將選擇的行2 5 SARAATT_APPL_NO的和在一列中我使打印出「否WSP」爲報告。

我是否匹配?比較?搜索?

這些是我想要的結果: Desired Results

我可以做這樣的事情和地方在代碼中添加呢?我想先選擇數據然後通過我選擇的循環。

DECLARE 
SARADAP_Count number() = 0; 
SARAATT_Count number() = 0; 

/* to keep going through the SARAATT_APPL_NO column until the end */ 
WHILE SA.SARADAP_APPL_NO not null 
    LOOP 
    /* If value being looked at in SARADAP = the value being looked at in SARAATT */ 
    IF SARADAP_APPL_NO = st.SARAATT_APPL_NO 
     /* Then add 1 to the count so we can compare the next value in SARADAP with the values in SARAATT*/ 
     THEN SARADAP_Count = SARADAP_Count + 1 
     /* Otherwise add 1 to the count to look at the next SARAATT value*/ 
     ELSE SARAATT_Count = SARAATT_Count + 1; 
     /* when we have compared all the values in SARAATT for one SARADAP value, and no  values matched, then print 'No WSP' in the "My Report Column" */ 
     WHEN SARADAP_APPL_NO <> st.SARAATT_APPL_NO THEN return 'NO WSP' in "MY REPORT COLUMN" 
     /* Now go to the next SARADAP row to compare that value with the values in SARAATT */ 
      LOOP 
      SARADAP_Count = SARADAP_Count +1 /* */ 
       END LOOP 
    END LOOP 

____________________________________________________________________________________

  1. 有我與工作兩個主表:SARADAP和SARAATT。 SARADAP是實際的入場申請。 SARAATT包含屬性並與應用程序具有共同的字段(SARAATT/SARADAP _PIDM,SARAATT/SARADAP _TERM_CODE和SARAATT/SARADAP _APPL_NO)
  2. 第三張表是SPRIDEN,包含該人員的個人信息。我只需要該表中的ID。
  3. 我的SELECT語句包括兩個主表的TERM_CODE和APPL_NO列,但WHERE子句不包含任何使兩個表中的TERM_CODE或APPL_NO匹配的條件。這意味着查詢只是收集信息並將其放入打印輸出中,而不是一致的(如下圖所示)。
  4. 問題:如果我添加一個條件(SARADAP_APPL_NO = st.SARAATT_APPL_NOSARADAP_TERM_CODE = st.SARAATT_TERM_CODE),則不會選擇需要的信息I
  5. 我真正需要的是查詢告訴我SARAATT_ATTS_CODE在與APPL_NO或TERM_CODE對應的行中沒有任何內容。我無法獲取該信息,因爲SARAATT_ATTS_CODE對於該行沒有任何內容,因此被查詢忽略。它有一個NOT NULL約束,所以我不能簡單地搜索NULL值。 (這是我嘗試通過執行LOOP或其他什麼來解決的真正問題)
  6. 由於查詢不會返回我需要的結果(顯示ATTS_CODE未填充的位置),我的工作輪的想法是查看在兩個APPL_NO列中查找不在兩個列中的值。那些將有一個沒有填充的SARAATT_ATTS_CODE行的人。
    這是實際的數據是在數據庫中(但我已經添加了我的專欄只是爲了顯示我想打印 Data

這些是我目前的查詢 Current Query Results的結果是什麼

toddlermenot,你要的Toddlerminot查詢中的結果與條款:
Results from WITH Clause 我按SARADAP_APPL_NO排序結果。請注意,紅色數據會混淆在一起。這不是真的應該在哪裏,200810和201510條款以及相應的應用程序編號(2和5)都不存在。這是當查詢只查找該表中存在的任何值(我相信它正在使用下一個可用值)並將其放在該行中時,因爲該行中實際上沒有任何值 - 或者該查詢與APPPL不匹配數字和條款。從Toddlerminot查詢

結果作爲一個整體 Results from Entire Toddlerminot Query 我通過SARADAP_APPL_NO排序的結果。

現在我將嘗試以「創建像一個[Toddlerminot]張貼在sqlfiddle說明[我]面對的問題。我將它添加到我的問題的問題。

我做到了,在小提琴的小例子。sqlfiddle.com/#!4/f4d10/2請注意,由於存在非空限制,因此我將空白值填入''中。我認爲現在實際上是http://www.sqlfiddle.com/#!4/aa83f/1,因爲我再次編輯它。我將數據類型更改爲數字(2,0),並輸入0而不是「'

這就是表格的樣子,這是每張表格中的數據。 Tables and Corresponding Data

+0

您的發佈標題;你可以簡單地做''select * from your_table where columna not in(select your distinct columnb from your_table)' – Rahul 2014-10-01 22:21:35

+0

@Rahul謝謝你的回覆。我不確定你的意思。總共涉及4列。我想比較/匹配/搜索的兩列是'st.SARAATT'和'sa.SARADAP'。 – 2014-10-01 22:29:29

+0

@Rahul我添加了'SA.SARADAP_APPL_NO不在(SELECT DISTINCT st.SARAATT_APPL_NO FROM SARAATT ST)',但沒有選擇行。 – 2014-10-01 22:34:34

回答

1

編輯3: 使用您發佈的數據模型,我已經建造這樣的:http://www.sqlfiddle.com/#!4/f1665/10

讓我知道這是否爲你。

幾件事情:

  • 所有4行SPRIDEN是重複的。所以只保留一個。
  • 表SORLCUR無處使用,不在公佈的截圖中。所以從查詢中刪除它。
  • 在引用的屏幕截圖中找不到任何引用的列。因此,他們從查詢中扣除。
  • 突出顯示的數據差異是由於在聯接條件中省略TERM_CODE而導致的笛卡爾聯接而引起的。
  • 報告欄按預期工作。

看起來你想要報告一個僞列。

如果我正確地分析你的問題,下面應該做的伎倆:

編輯:基於您的評論/編輯,我已經更新了查詢:

編輯2: 這是仍然很難說沒有整個數據模型,但如果我理解正確有2個問題:

1 - 紅色突出顯示的數據:我的猜測 - >這是因爲使用FULL OUTER JOIN而不是LEFT OUTER JOIN。更新後的代碼如下。試着讓我知道。

2 - 「我的報告列」顯示爲空白:還沒有線索爲什麼這不起作用,您的SQL小提琴似乎顯示它的工作。

WITH t AS 
(
    SELECT DISTINCT 
      SP.SPRIDEN_ID AS "ID", 
      SP.SPRIDEN_LAST_NAME AS "LAST", 
      SP.SPRIDEN_FIRST_NAME AS "FIRST", 
      SA.SARADAP_TERM_CODE_ENTRY AS "APP_TERM", 
      SA.SARADAP_ADMT_CODE AS "ADM_TYPE", 
      ST.SARAATT_TERM_CODE AS "TERM_CODE", 
      ST.SARAATT_APPL_NO "APPL_NO1", 
      SA.SARADAP_APPL_NO "APPL_NO2" 
    FROM 
     SPRIDEN SP 
     JOIN SARADAP SA 
     ON SP.SPRIDEN_PIDM = SA.SARADAP_PIDM 
     JOIN SORLCUR SR 
     ON SP.SPRIDEN_PIDM = SR.SORLCUR_PIDM 
     LEFT OUTER JOIN SARAATT ST 
     ON SP.SPRIDEN_PIDM = ST.SARAATT_PIDM 
    WHERE 
     SP.SPRIDEN_CHANGE_IND IS NULL 
     AND SA.SARADAP_ADMT_CODE IN ('SP', 'XT') 
) 
SELECT 
    ID, 
    LAST, 
    FIRST, 
    APP_TERM, 
    ADM_TYPE, 
    TERM_CODE, 
    APPL_NO1, 
    APPL_NO2, 
    CASE 
    WHEN (SELECT 
      COUNT(1) 
     FROM 
      t t2 
     WHERE 
      t1.APPL_NO2=t2.APPL_NO1) = 0 THEN 'NO WSP' 
    END AS "My Report Column" 
FROM 
    t t1; 

我還沒有測試過這個語法錯誤,所以隨時糾正它們。我確信有一個分析功能解決方案,但我認爲這應該也是一樣。

+0

感謝您的回答。直到明天我工作之前,我無法測試它。這是我需要的:查看ST.SARAATT_APPL_NO和SA.SARADAP_APPL_NO兩列。查找行SARADAP_APPL_NO = 2和SARADAP_APPL_NO = 5在任何SARAATT_APPL_NO行中都沒有匹配。拉出那些沒有匹配的行。 明天我會測試這個。我希望你會回來。 :) – 2014-10-02 07:23:35

+0

@AuntieAnita:當然,請檢查並讓我知道。上面的查詢不會過濾出具有SARAATT_APPL_NO = SARADAP_APPL_NO的記錄。相反,它將顯示具有「無WSP」值的所有記錄(如您在問題中陳述的)和所需的記錄(即SARADAP_APPL_NO <> SARAATT_APPL_NO),而其他記錄對於「我的報告列」將具有NULL。 – toddlermenot 2014-10-02 07:33:44

+0

:(如果兩列字面上不匹配,它將放棄沒有WSP。它需要做到這一點:看第2列中的值,第1行(C2R1)是C1中的某個值?否,打印「無WSP」中的'我的報告欄' - C1中的C2R2否,打印否C1中的WSP-C2R3?是,不打印任何東西等等...... 因此,需要查看C2中的每個值,看它是否在C1然後決定是否打印「No WSP」 – 2014-10-02 15:49:46

0

**感謝Todderlmenot(https://stackoverflow.com/users/350136/toddlermenot)的所有時間和精力!你幫助我解決了一半的問題,並在這個過程中學到了很多東西! 此外,感謝Vignesh Lakshmirajan幫助我解決另一半問題**

事實證明,我可以使用MINUS來確定列中缺少的行。

/* 
Author: 
Date: 30-Sep-14 
Purpose: Select records of Special or Transient applicants whose Attribute field (SAAADMS - Contacts, Cohorts, Attributes) does contain "WSP" 

NOTE: For those records missing the WSP, there will be no rows in SARAATT for the term/application number in which WPS is missing. 
Those rows will simply not exist. 

SARADAP_TERM SARADAP_APPL SARAATT_TERM SARAATT_APPL SARAATT_ATTS_CODE  
    200810   2    200810   2    WPS 
    200910   3      
    201080   4    201080   4    WPS 
    201350   5      

Use SARADAP MINUS SARAATT to retreive the rows for which there is no SARAATT. 
We can use this becuase for rows in which there is no WSP, there will also be no APPL_NO or TERM_CODE  
*/ 



Select 
sp.spriden_id as "ID", 
SP.SPRIDEN_LAST_NAME as "Last", 
SP.SPRIDEN_FIRST_NAME as "First", 
SA.SARADAP_TERM_CODE_ENTRY as "SARADAP_TERM_CODE_ENTRY", 
sa.SARADAP_APPL_NO as "SARADAP_APPL_NO" 

FROM  
SPRIDEN SP 
JOIN SARADAP SA 
on sp.spriden_pidm = sa.saradap_PIDM 

WHERE 
Sp.spriden_change_ind is null 
AND 
SA.SARADAP_TERM_CODE_ENTRY >= '201510' 
AND 
SA.SARADAP_ADMT_CODE in ('SP', 'XT') 


MINUS 


SELECT 
sp.spriden_id as "ID", 
SP.SPRIDEN_LAST_NAME as "Last", 
SP.SPRIDEN_FIRST_NAME as "First", 
st.SARAATT_TERM_CODE as "SARAATT_TERM_CODE", 
st.SARAATT_APPL_NO as "SARAATT_APPL_NO" 

FROM 
SPRIDEN SP 
LEFT OUTER JOIN SARAATT ST 
on sp.spriden_pidm = ST.SARAATT_PIDM 

WHERE 
Sp.spriden_change_ind is null