2012-07-16 25 views
1

我有兩個表格說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的

回答

6

使用外連接有條件鏈接表A和B,然後使用CASE()語句來測試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 
+1

這是一段華麗的代碼 - 感謝您省下的時間! – America 2014-05-28 17:02:34

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。

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的一個子集 - 你已經知道這些記錄應與您的別名列是被標記。 從其存在或不存在於另一個記錄集的記錄集中移除記錄的傳統方法當然是使用EXISTS子句。 EXISTS子句的優點是它是一個布爾運算符,並向該調用返回TRUE或FALSE。而且這個返回發生時不需要對錶格進行全面掃描 - 因此它更快(通常)。 你也可以選擇使用MINUS子句,它可能更有效。嘗試打開EXPLAIN PLAN。

+0

如果B真的具有與A相同的數據結構(OP不清楚「B是A的子集」實際上是什麼意思),這可能是非常有效的解決方案。 – APC 2012-07-16 15:20:19

相關問題