2

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

4

3 回答 3

9

使用外连接有条件地链接表 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

请注意,这仅在只有 0 或 1 个 B.COLUMN1 实例时才能正常工作。如果 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
于 2012-07-16T13:25:22.743 回答
2

你可以尝试这样的事情:

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

我的 PL-SQL 有点生疏,例子取自这里

您还可以在 B 上执行 LEFT JOIN,并查看 B.Column1 是否为 NULL。

于 2012-07-16T10:53:36.330 回答
2
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 子句,它可能更有效。尝试打开解释计划。

于 2012-07-16T13:38:06.720 回答