在两个条件下联接两个表,如果失败则联接到带有空白单元格的行

时间:2018-07-12 14:40:12

标签: sql sql-server

我必须在两个条件下联接两个表。我希望如果第二个条件不成立,但表1中有一个空白单元格(不是null,而是空白”),然后加入该行。如果第二个条件不成立,则返回零。

加入表1和表2-从表1中返回表2和列3。

表1

(A, 1, 0.25),
(A, 2, 0.50),
(A, 3, 0.25),
(A, , 0.50),
(B, 1, 0.25),
(B, 2, 0.50),
(B, 3, 0.25),

表2

(A, 1),
(A, 2),
(A, 3),
(A, 5),
(B, 1),
(B, 2),
(B, 3),
(B, 5)

我想退货

(A, 1, 0.25),
(A, 2, 0.50),
(A, 3, 0.25),
(A, 5, 0.50),
(B, 1, 0.25),
(B, 2, 0.50),
(B, 3, 0.25),
(B, 5, 0.00)

3 个答案:

答案 0 :(得分:4)

您可以在子查询中使用COALESCE(arg1,arg2,…)获取表2中每条记录的十进制数。COALESCE依次遍历其参数,并返回第一个非空值。

这正是您想要做的: arg1:在两个条件下都查找匹配项。 arg2:查找匹配的字母,但表1中的int值为空。 arg3:如果arg1或arg2中没有匹配项,则返回0

示例:

DECLARE @table1 TABLE (letter CHAR(1), num1 INT, num2 NUMERIC(5,2))
DECLARE @table2 TABLE (letter CHAR(1), num1 INT)

INSERT INTO @table1 VALUES 
('A', 1, 0.25),
('A', 2, 0.50),
('A', 3, 0.25),
('A', null, 0.50),
('B', 1, 0.25),
('B', 2, 0.50),
('B', 3, 0.25)

INSERT INTO @table2 VALUES 
('A', 1),
('A', 2),
('A', 3),
('A', 5),
('B', 1),
('B', 2),
('B', 3),
('B', 5)

SELECT t2.*, 
    COALESCE(
        (SELECT TOP 1 num2 FROM @table1 WHERE letter = t2.letter AND num1 = t2.num1), 
        (SELECT TOP 1 num2 FROM @table1 WHERE letter = t2.letter AND num1 IS NULL), 
        0
    ) AS missing_number
FROM @table2 t2

收益:

letter  num1    missing_number
A       1       0.25
A       2       0.50
A       3       0.25
A       5       0.50
B       1       0.25
B       2       0.50
B       3       0.25
B       5       0.00

答案 1 :(得分:1)

我将使用left joincoalesce()

select t2.*, coalesce(t1.col3, 0)
from table2 t2 left join
     table1 t1
     on t2.col1 = t1.col1 and t2.col2 = t1.col2;

或者,如果您希望将''作为默认值,请使用两个left join

select t2.*, coalesce(t1.col3, tt1.col3, 0)
from table2 t2 left join
     table1 t1
     on t2.col1 = t1.col1 and t2.col2 = t1.col2 left join
     table1 tt1
     on tt1.col1 = t2.col1 and tt1.col2 = '' and t1.col2 is null;

或者,使用apply

select t2.*, coalesce(t1.col3, 0)
from table2 outer apply
     (select top (1) t1.*
      from table1 t1
      where t1.col1 = t2.col1 and t1.col2 in ('', t2.col2)
      order by t1.col2 desc
     ) t1;

答案 2 :(得分:1)

基于TOP 1 WITH TIES ... ORDER BY ...:

SELECT TOP 1 WITH TIES 
  table2.char_value, 
  table2.int_value, 
  isnull(table1.numeric_value, 0.0)
FROM 
  (VALUES 
  ('A', 1), ('A', 2), ('A', 3), ('A', 5), 
  ('B', 1), ('B', 2), ('B', 3), ('B', 5)
  ) table2(char_value, int_value)
LEFT JOIN 
  (VALUES 
  ('A', 1, 0.25), ('A', 2, 0.50), ('A', 3, 0.25), ('A', null, 0.50), 
  ('B', 1, 0.25), ('B', 2, 0.50), ('B', 3, 0.25)
  ) table1(char_value, int_value, numeric_value)
ON table2.char_value = table1.char_value
AND CASE 
  WHEN table2.int_value = table1.int_value THEN 1 
  ELSE CASE WHEN table1.int_value IS NULL THEN 1 
  END END = 1 
ORDER BY ROW_NUMBER() OVER(PARTITION BY table2.char_value, table2.int_value ORDER BY table1.int_value DESC)