根据多个条件连接两个表

Hen*_*ieR 2 sql-server-2005 join sql-server

我有两个表产品和职位。

产品:

id BIGINT PRIMARY KEY,
product VARCHAR(100),
criterium1 VARCHAR(100),
criterium2 VARCHAR(100)
Run Code Online (Sandbox Code Playgroud)

职位:

id BIGINT PRIMARY KEY,
position VARCHAR(100),
criterium1 VARCHAR(100),
criterium2 VARCHAR(100)
Run Code Online (Sandbox Code Playgroud)

每个表都有criterium1和criterium2。我想要一个包含职位和产品之间连接的结果集。对于每个职位,我都想要与 criterium1 或 criterium2 匹配的相应产品;当 criterium1 找不到或为 NULL 时,它需要在 criterium2 上匹配。

SQL 语句会是什么样的?

到目前为止,我已经尝试过:

SELECT * FROM positions pos 
INNER JOIN products pro 
ON COALESCE(pos.criterium1, pos.criterium2,'') 
    = COALESCE( pro.criterium1, pro.criterium2,'') 
Run Code Online (Sandbox Code Playgroud)

然而,这不匹配pro.criterium1pos.criterium1pro.criterium2pos.criterium2

补充:对不起,我的要求有点模糊。让我试着完成这幅画。

我们使用的是 SQL Server 2005。

products:

id   product   criterium1   criterium2
 1    pro1       AAA1         910
 2    pro2       106          BB2
 3    pro3       AB1          XXY

positions:

id  position  criterium1  criterium2
 1    pos1       NULL         910
 2    pos2       106          CCC
 3    pos3       XXX          BB2
 4    pos4       AA1          XXY
 5    pos5       NULL         123
Run Code Online (Sandbox Code Playgroud)

我正在寻找的是使用条件匹配的表格连接,我想将位置与产品相匹配。首先我想匹配criterium1。如果我在 criterium1 上找不到匹配项或位置 criterium1 为 NULL,我需要在 criterium2 上匹配。

在上面的例子中,预期的结果集是:

resultset
positionId  productId
 1            1 (no match on criterium1 since NULL, match on criterium2 )
 2            2 (match on criterium1)
 3            2 (no match on criterium1, match on criterium2 )
 4            1 (match on criterium1, criterium2 match is disregarded)
Run Code Online (Sandbox Code Playgroud)

我只想匹配positions.criterium1products.criterium1positions.criterium2使用products.criterium2

Lei*_*fel 9

假设 pro1,criterium1 应该是 AA1,这会产生您正在寻找的结果:

SELECT pos.id, pro.id, pos.criterium1, pos.criterium2
   , pro.criterium1, pro.criterium2 
FROM Positions pos
JOIN Products pro ON pos.criterium1 = pro.criterium1 
   OR (pos.criterium2 = pro.criterium2
   AND pos.id NOT IN (
      SELECT posx.id FROM Positions posx
      JOIN Products prox ON posx.criterium1 = prox.criterium1
   ))
ORDER BY 1;
Run Code Online (Sandbox Code Playgroud)

测试查询(仅在 Oracle 中测试):

WITH Products AS (
   SELECT 1 id, 'AA1' criterium1, '910' criterium2 FROM dual UNION ALL
   SELECT 2 id, '106'  criterium1, 'BB2' criterium2 FROM dual UNION ALL
   SELECT 3 id, 'AB1'  criterium1, 'XXY' criterium2 FROM dual
   ),
   Positions AS (
   SELECT 1 id, NULL  criterium1, '910' criterium2 FROM dual UNION ALL
   SELECT 2 id, '106' criterium1, 'CCC' criterium2 FROM dual UNION ALL 
   SELECT 3 id, 'XXX' criterium1, 'BB2' criterium2 FROM dual UNION ALL 
   SELECT 4 id, 'AA1' criterium1, 'XXY' criterium2 FROM dual UNION ALL 
   SELECT 5 id, NULL  criterium1, '123' criterium2 FROM dual    
   )   
SELECT pos.id, pro.id, pos.criterium1, pos.criterium2
   , pro.criterium1, pro.criterium2 
FROM Positions pos
JOIN Products pro ON pos.criterium1 = pro.criterium1 
   OR (pos.criterium2 = pro.criterium2
   AND pos.id NOT IN (
      SELECT posx.id FROM Positions posx
      JOIN Products prox ON posx.criterium1 = prox.criterium1
   ))
ORDER BY 1;
Run Code Online (Sandbox Code Playgroud)

  • 乐意效劳。在本网站上表达感谢的方式是通过单击旁边的向上箭头对答案进行投票。如果答复令人满意地回答了您的问题,那么您还应该选中答案旁边的复选标记。有关更多信息,请参阅 http://dba.stackexchange.com/faq#reputation。 (2认同)