2014-01-24 101 views
0

下面我有sql select從表中檢索值。我想從tableA中檢索值,而不管tableB中是否有匹配的行。以下給出了非空值和空值。如果存在非空行,如何過濾出空值,但是否保留空值?只有當它們存在於SQL中時才過濾掉空值選擇

SELECT a.* FROM 
(
    SELECT 
      id, 
      col1, 
      coll2 
     FROM tableA a LEFT OUTER JOIN tableB b ON b.col1=a.col1 and b.col2='value' 
     WHERE a.id= @id 
      AND a.col2= @arg 

) AS a 

ORDER BY col1 ASC 
+0

您錯過了一個代碼段。 )缺少它的朋友。 – Zane

回答

1

可通過計算使用窗函數匹配的數量做到這一點。然後,要麼返回所有行A,如果沒有匹配的B行,或只返回那些匹配的行:

select id, col1, col2 
from (SELECT a.id, a.col1, a.coll2, 
      count(b.id) over() as numbs 
     FROM tableA a LEFT OUTER JOIN tableB b ON b.col1=a.col1 and b.col2='value' 
     WHERE a.id = @id AND a.col2= @arg 
    ) ab 
where numbs = 0 or b.id is not null; 
1

篩選出來在WHERE子句

SELECT 
    id, 
    col1, 
    coll2 
FROM tableA a LEFT OUTER JOIN tableB b ON b.col1=a.col1 and b.col2='value' 
WHERE a.id= @id 
    AND a.col2= @arg 
    AND A.Col1 IS NOT NULL -- HERE 
) AS a 

ORDER BY col1 ASC 
0

出於某種原因,人們喜歡寫馬爾科代碼,把一個過濾器(b.col2 = '值')在JOIN子句中。雖然這起作用,但這不是好習慣。

此外,你應該習慣於在正確的序列中有ON子句。我們將表A連接到表B,爲什麼將它寫爲B.col1 = A.col1,它是向後的。

儘管上述說法有效,但它絕對可以改進。

我創建了以下測試表。

-- Just playing 
use tempdb; 
go 

-- Table A 
if object_id('A') > 0 drop table A 
go 
create table A 
(
    id1 int, 
    col1 int, 
    col2 varchar(16) 
); 
go 

-- Add data 
insert into A 
values 
(1, 1, 'Good data'), 
(2, 2, 'Good data'), 
(3, 3, 'Good data'); 

-- Table B 
if object_id('B') > 0 drop table B 
go 
create table B 
(
    id1 int, 
    col1 int, 
    col2 varchar(16) 
); 

-- Add data 
insert into B 
values 
(1, 1, 'Good data'), 
(2, 2, 'Good data'), 
(3, NULL, 'Null data'); 

這裏是改進的語句。我選擇文字而不是變量。但是,您可以更改您的示例。

-- Filter non matching records 
SELECT 
    A.* 
FROM A LEFT OUTER JOIN B ON 
    A.col1 = B.col1 
WHERE 
    B.col1 IS NOT NULL AND 
    A.id1 in (1, 2) AND 
    A.col2 = 'Good data' 
ORDER BY 
    A.id1 DESC 

這裏是輸出圖像。

enter image description here

相關問題