我有两个表说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
答案 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。