为两个表之间的公共行添加标志

时间:2012-07-16 10:48:54

标签: sql oracle

我有两个表说A和B.B是A的子集。我想要做的是:向表A添加一个标志列(仅用于查看,而不是永久保存在表中)以及此值对于A和B之间的公共行,标志应为yes,对于非公共行,标志应为no。例如:

A table
Column1 Column2 Column3
X1      X2      X3
Y1      Y2      Y3
Z1      Z2      Z3

select * from A where column1=Y1; to get B

现在我的最终输出应该是

Column1 Column2 Column3 FLAG
X1      X2      X3      NO   
Y1      Y2      Y3      YES 
Z1      Z2      Z3      NO

我必须在1 sql语句中提取代码块以下的所有内容(提取B并添加标志)。 我只能提取B.无法添加标志

使用oracle 11.2.0.2.0,sqlplus

3 个答案:

答案 0 :(得分:7)

使用外部联接有条件地链接表A和B,然后使用CASE()语句来测试A中的给定行是否与B中的行匹配。

select a.*
       , case when b.column1 is not null then 'YES' else 'NO' end as flag
from a left outer join b
        on a.column1 = b.column1

请注意,仅当B.COLUMN1只有0或1个实例时才能正常工作。如果B包含任何COLUMN1值的多个实例,则可以使用此变体:

select a.*
       , case when b.column1 is not null then 'YES' else 'NO' end as flag
from a left outer join ( select distinct column1 from b ) b
        on a.column1 = b.column1

答案 1 :(得分:1)

您可以尝试这样的事情:

SELECT A.*, 
       CASE WHEN EXISTS 
            (SELECT Column1 FROM B WHERE Column1=A.Column1) 
       THEN "YES" 
       ELSE "NO"
       END
FROM A

我的PL-SQL有点生疏,例子来自here

你也可以在B上进行LEFT JOIN,看看B.Column1是否为NULL。

答案 2 :(得分:1)

SELECT A.*, 'NO' 
FROM A
WHERE NOT EXISTS 
(SELECT 1 FROM B
WHERE B.COL1 = A.COL1
AND B.COL2 = A.COL2
AND B.COL3 = A.COL3) -- gets records only in A
UNION ALL 
(SELECT B.*, 'YES')  -- gets B records which are a subset of A

由于B是A的子集 - 您已经知道这些记录应该为您的别名列标记为YES。 从一个记录集中删除记录的经典方法当然是使用EXISTS子句存在或不存在于另一个记录集中。 EXISTS子句的优点是它是一个布尔运算符,并且对调用返回TRUE或FALSE。并且这种返回发生时无需对表进行全面扫描 - 因此它更快(通常)。 您也可以选择使用MINUS子句,它可能更有效。尝试打开EXPLAIN PLAN。