簡體   English   中英

Select 基於兩個不同 where 子句/連接的表中的列 - 如果一個列匹配,則使用該列,如果不匹配則使用另一個

[英]Select columns from a table based on two different where clauses / joins - if one column matches use that, if not then use another

我正在嘗試創建一個 SQL 查詢,該查詢將基於表 1 中兩列之一之間的相等性從表 2 中SELECT列。

我知道我不能在多個列上加入。 從概念上講,我希望它在一個公共列上加入,稱為第 1 列,如果兩個表中都存在第 1 列(不是 NULL),否則在不同的公共列上加入,稱為第 2 列。

由於像這樣的JOIN是不合法的,我想出了一個具有多個COALESCE的替代方案,但它對於我的目的來說太慢了(這些表中會有很多行):

兩個WHERE子句表示檢查兩個表中是否存在第一列,然后檢查第二列。

我的查詢需要 select n來自 table2 的列。 目前如何我必須添加n 個COALESCE語句,這確實是低效的。

有誰知道一次執行此查詢的方法,即無需多次合並? 或者另一種讓它發揮作用的方法?

最小可重現示例:

/* Definition query */
CREATE TABLE [dbo].[table1](
    [foo] [bigint] NULL,
    [bar] [nvarchar](50) NULL,
    [qux] [bigint] NULL,
    [quux] [nvarchar](50) NULL
); 

CREATE TABLE [dbo].[table2](
    [baz] [nvarchar](50) NULL,
    [qux] [bigint] NULL,
    [quux] [nvarchar](50) NULL,
    [corge] [bigint] NULL
);

/* Sample data */
INSERT [dbo].[table1] ([foo], [bar], [qux], [quux]) VALUES (1, N'asd', 345, NULL);
INSERT [dbo].[table1] ([foo], [bar], [qux], [quux]) VALUES (2, N'fas', NULL, N'abc');
INSERT [dbo].[table1] ([foo], [bar], [qux], [quux]) VALUES (3, N'fasfdjka', 678, NULL);
INSERT [dbo].[table1] ([foo], [bar], [qux], [quux]) VALUES (4, N'jggiy', NULL, N'def');
INSERT [dbo].[table2] ([baz], [qux], [quux], [corge]) VALUES (N'afsfsaf', 345, N'xyz', 764694659);
INSERT [dbo].[table2] ([baz], [qux], [quux], [corge]) VALUES (N'jjuiku', 8910, N'abc', 519285912);
INSERT [dbo].[table2] ([baz], [qux], [quux], [corge]) VALUES (N'gghsd', 678, N'vuw', 152512512);
INSERT [dbo].[table2] ([baz], [qux], [quux], [corge]) VALUES (N'oolas;p', 111213, N'def', 921839129);


/* Select query */
SELECT t1.foo, t1.bar  ,
    COALESCE(  
    (  
    SELECT top 1 t2.baz 
   FROM  table2 as t2  
    WHERE t2.qux = t1.qux   
    ),  
    (  
    SELECT top 1 t2.baz 
    FROM  table2 as t2  
    WHERE  t2.quux = t1.quux
    )  
    ) AS baz, 
    COALESCE(  
    (  
    SELECT top 1 t2.corge 
   FROM  table2 as t2  
    WHERE t2.qux = t1.qux   
    ),  
    (  
    SELECT top 1 t2.corge 
    FROM  table2 as t2  
    WHERE  t2.quux = t1.quux
    ) ) AS corge  
FROM  table1 as t1

這是我得到的結果,這是期望的結果。 但是當你在大表上操作時,它太慢了,這使得它不可行。

合並結果

我嘗試用INTERSECT代替COALESCE但它給了我這個結果NULL的兩列中,這是不希望的:

SELECT t1.foo, t1.bar  , 
    (SELECT top 1 t2.baz 
   FROM  table2 as t2  
    WHERE t2.qux = t1.qux
    INTERSECT  
    SELECT top 1 t2.baz 
    FROM  table2 as t2  
    WHERE  t2.quux = t1.quux)
    AS baz,
    (SELECT top 1 t2.corge 
   FROM  table2 as t2  
    WHERE t2.qux = t1.qux   
    INTERSECT
    SELECT top 1 t2.corge 
    FROM  table2 as t2  
    WHERE  t2.quux = t1.quux)
    AS corge
FROM  table1 as t1

相交結果

我嘗試使用EXCEPT而不是COALESCE ,它給了我不同的結果,但不是想要的結果:

SELECT t1.foo, t1.bar  , 
    (SELECT top 1 t2.baz 
   FROM  table2 as t2  
    WHERE t2.qux = t1.qux
    EXCEPT  
    SELECT top 1 t2.baz 
    FROM  table2 as t2  
    WHERE  t2.quux = t1.quux)
    AS baz,
    (SELECT top 1 t2.corge 
   FROM  table2 as t2  
    WHERE t2.qux = t1.qux   
    EXCEPT
    SELECT top 1 t2.corge 
    FROM  table2 as t2  
    WHERE  t2.quux = t1.quux)
    AS corge
FROM  table1 as t1

結果除外

謝謝

像這樣的東西?

select 
    t1.foo
    ,t1.bar
    ,isnull(t2.baz, t3.baz) as baz 
    ,isnull(t2.corge, t3.corge) as corge
from #table1 t1
left outer join #table2 t2 on t1.qux = t2.qux
left outer join #table2 t3 on t1.quux = t3.quux

回報:

酒吧 巴茲 峽谷
1 asd afsfsaf 764694659
2 jjuiku 519285912
3 法斯迪卡 gghsd 152512512
4 吉吉 哎呀;p 921839129

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM