Oracle SQL - 比较列 - SELECT记录中没有匹配项的值

时间:2014-10-01 22:18:10

标签: sql oracle search compare match

背景
我编写的大多数脚本都会搜索缺少数据的记录。我使用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
我必须欺骗它给我我想要的数据。我相信我已经考虑过要检索它的过程,但我不知道如何编码它!

这是实际数据。注意:我不知道空白字段中有什么。约束是" 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_NO时返回的数据。 Data - with app number condition

为了检索我需要的数据,我想做这样的事情:
从当前SELECT语句中选择所有数据 然后,对于每个SARADAP_APPL_NO,在SARAATT_APPL_NO中找到它的匹配。
SELECT那些没有匹配项的行,并在列中打印“No WSP”我为报告创建了JUST(不在数据库中)。
这就是我的意思"它有匹配吗?": 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)中,它将为SARAATT_APPL_NO选择2 5行,并在我为报告制作的列中打印出“无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. 第3张表是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),则不会选择我真正所需的信息。
  5. 我真正需要的是查询告诉我SARAATT_ATTS_CODE在与APPL_NO或TERM_CODE对应的行中没有任何内容。我无法获得这些信息,因为SARAATT_ATTS_CODE没有&#34;没有&#34;在该行中,因此被查询忽略。它有一个NOT NULL约束,所以我不能简单地搜索NULL值。 (这是我试图通过LOOP或其他东西来解决的真正问题)
  6. 由于查询不会返回我需要的结果(显示ATTS_CODE未填充的位置),我的工作原理是查看两个APPL_NO列并查找不在BOTH列中的值。那些将是没有人口的SARAATT_ATTS_CODE行的人 这是数据库中的实际DATA(但我添加了My Column只是为了显示我想要打印的内容 Data
  7. 这些是我当前查询的结果 Current Query Results

    幼儿园主,您在WITH子句中询问了Toddlerminot查询的结果:
    Results from WITH Clause 我按SARADAP_APPL_NO对结果进行了排序。请注意,红色数据混合在一起。它并不是真正的应有之处,缺少200810和201510术语以及相应的应用程序编号(2和5)。这是当查询只是查找该表中存在的任何值时(我相信它正在使用下一个可用值)并将其放在该行中,因为该行中实际上没有任何内容 - 或者查询与APPPL不匹配数字和TERMS彼此。

    整个Toddlerminot查询的结果 Results from Entire Toddlerminot Query 我按SARADAP_APPL_NO排序结果。

    我现在将尝试创建一个小例子,例如在sqlfiddle中发布的[Toddlerminot],以说明[我]面临的问题。我会把它添加到我的问题中。

    我是在小提琴中做到的。 sqlfiddle.com/#!4/f4d10/2请注意我放入&#39; &#39;对于空值,因为存在非空约束。我认为它现在实际上是http://www.sqlfiddle.com/#!4/aa83f/1,因为我再次编辑它。我将数据类型更改为数字(2,0)并输入0而不是&#39; &#39;

    这是表的方式,这是Maria Smith每个表中的数据。 Tables and Corresponding Data

2 个答案:

答案 0 :(得分:1)

编辑3: 使用您发布的数据模型,我构建了这个:http://www.sqlfiddle.com/#!4/f1665/10

请告诉我这是否适合您。

一些事情:

  • SPRIDEN中的所有4行都是重复的。所以只保留一个。
  • 表SORLCUR无处使用,不会在发布的屏幕截图中使用。所以从查询中解决了这个问题。
  • 在发布的屏幕截图中找不到引用的几列。所以从查询中解决了这些问题。
  • 您突出显示的数据差异是由于在连接条件中遗漏了TERM_CODE而导致的笛卡尔连接造成的。
  • 报告列按预期工作。

您希望使用伪列进行报告。

如果我正确地解析了你的问题,下面应该可以解决问题:

编辑:根据您的评论/编辑,我更新了查询:

编辑2: 没有整个数据模型仍然很难说,但如果我理解正确有两个问题:

1 - 以红色突出显示的数据:我的猜测 - &gt;这是因为使用了FULL OUTER JOIN而不是LEFT OUTER JOIN。更新此内容在下面的代码中。试着让我知道。

2 - &#34;我的报告栏&#34;一片空白:Haven得知道为什么这不起作用,你的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;

我还没有对语法错误进行测试,所以请随意纠正它们。我确信有一个解析函数解决方案,但我认为这也应该工作。

答案 1 :(得分: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