内/左外连接使用条件列匹配

时间:2015-02-07 16:17:40

标签: sql-server join

我需要一些左外连接/内连接的帮助,条件如下;

select a.val1,a.val2,b.val1,b.val2,..
from tableA a 
inner join tableB b 
on (if a.val1<>0 then a.val1=b.val1
  and if a.val2<>0 then a.val2=b.val2
  and if a.val3<>0 then a.val3=b.val3
  and if a.val4<>0 then a.val4=b.val4)
where a.description='ABC'

如果值不为零,我想仅根据条件匹配某些列

任何帮助将不胜感激。 我试过CASE WHEN等等没有任何成功。 请提供正确的语法以匹配上面的示例,因为我不是这方面的专家。 感谢。

ZEE

感谢你的回复Hogan,我知道你的例子很好,但是由于这个原因我没有成功 我对情景缺乏解释。

请在此处查看示例数据;

MainTable                               
MakeID|Make---|ModelID|Model|ColorID|Color---|SizeID|Size|Mat
1     |Polo   | 1     | LT  |  1    |Black   | 1    | S  |Cot
1     |Polo   | 1     | LT  |  1    |Black   | 2    | M  |Pol
1     |Polo   | 2     | XT  |  2    |Red     | 3    | S  |Pol
2     |Gap    | 3     | NK  |  3    |Black   | 4    | S  |PolCot
2     |Gap    | 4     | LK  |  4    |Red     | 5    | M  |Wool
3     |Arrow  | 5     | MM  |  5    |Black   | 6    | L  |Wool
3     |Arrow  | 5     | MM  |  6    |White   | 7    | XL |Pol
3     |Arrow  | 6     | LM  |  7    |Black   | 8    | S  |Cot
4     |Zig    | 7     | HG  |  7    |Green   | 9    | S  |PolCot
4     |Zig    | 7     | HG  |  7    |Green   | 10   | M  |Wool
MapTable                        
MapID|ItemID|MakeMatch|ModelMatch|ColorMatch|SizeMatch|Material
1    |ABC   | 1       | 1        | 1        | 1       |Cot
2    |ABC   | 1       | 2        | 0        | 0       |Pol
3    |ABC   | 3       | 6        | 0        | 0       |Wool
4    |ABC   | 4       | 7        | 7        | 0       |PolCot
5    |XY    | ..      | ..       | ..       | ..      |..
6    |XY    | ..      | ..       | ..       | ..      |..
7    |XY    | ..      | ..       | ..       | ..      |..

结果我希望拉: 下面之一;

MapID|Make--|Model|Color--|Size|Mat
1    |Polo  |LT   |Black  |S   |Cot
2    |Polo  |XT   |null   |null|Pol
3    |Arrow |LM   |null   |null|Wool
4    |Zig   |HG   |Green  |null|PolCot

或以下;

MapID|Concat-Field
1    |Polo-LT-Black-S-Cot
2    |Polo-XT--Pol
3    |Arrow-LM--Wool
4    |Zig-HG-Green--PolCot

使用maptable,我需要拉出包含itemid ='ABC'的记录,并从MainTable中获取每个表示为MakeMatch,ModelMatch,ColorMatch,SizeMatch的iD的匹配值。它总是以MakeMatch,ModelMatch,ColorMatch,SizeMatch的顺序填充值。 MakeMatch总是会被填充,但是其他字段可以为零。例如。如果ColorMatch为Zero,则其父级MakeMatch,ModelMatch将始终填充。但是如果ColorMatch为零,SizeMatch也将为零。

所以我尝试了使用内连接和左外连接的不同方法,但无济于事。 能不能请您告诉我在这里显示预期结果的最佳方法是什么。

注意:由于包含无格式代码而导致发布问题。请逐节尝试
谢谢Hogan, 感谢您的回复。您提供的代码,产生了我想要的结果, 除了我必须包括 select distinct

SELECT distinct M.MapID, Model.Make, Model.Model, Color.Color, Size.Size, M.Material
FROM MapTable AS M
JOIN (SELECT MakeID, Make 
  FROM MainTable 
  GROUP BY MakeID, Make) AS Make ON M.MakeMatch = Make.MakeID
LEFT JOIN MainTable Model ON M.MakeMatch = Model.MakeID AND M.ModelMatch = Model.ModelID
LEFT JOIN MainTable Color ON M.MakeMatch = Color.MakeID AND M.ColorMatch = Color.ColorID
LEFT JOIN MainTable Size ON M.MakeMatch = Size.MakeID AND M.SizeMatch = Size.SizeID
where M.ItemID = 'ABC'

然而,在一个场景中,虽然结果略有不同。 当我向mapTable添加一条记录时如下

7    |ABC   | 2       | 0        | 0        | 0       |Wool

添加此记录后,结果如下;

MapID|Make--|Model|Color--|Size|Mat
1    |Polo  |LT   |Black  |S   |Cot
2    |Polo  |XT   |null   |null|Pol
3    |Arrow |LM   |null   |null|Wool
4    |Zig   |HG   |Green  |null|PolCot
7    |null  |null |null   |null|Wool

最后的第7张唱片没有拉动Make。

仅为了您的信息,我尝试了以下代码,以获得正确的结果。但我知道这不是一种有效的方法。 如果您可以查看下面的代码并建议更好的编码将非常感激。

select Maptable.mapid ,concat(
(select top 1 make from MainTable where MainTable.makeid=MapTable.MakeMatch)+'--->', 
(select top 1 model from MainTable where MainTable.modelid=maptable.ModelMatch)+'--->', 
(select top 1 size from MainTable where MainTable.SizeID=MapTable.SizeMatch)+'--->',
(select top 1 Color from MainTable where MainTable.ColorID=MapTable.ColorMatch),
maptable.material) as Selection
from maptable  where maptable.itemid = 'ABC' 

这个产生了下面的结果,我需要它。


    MapID | Detail
    1      Polo--->LT--->S--->Black-->Cot
    2      Polo--->XT--->Pol
    3      Arrow--->LM--->Wool
    4      Zig--->HG--->Black-->PolCot
    7      Gap--->Wool

如果你能为我提供更有效的编码,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

好的,现在我看到你的示例数据,我可以给你正确的SQL:

SELECT M.MapID,  Make.Make, Model.Model, Color.Color, Size.Size, M.Material
FROM MapTable AS M
JOIN (SELECT MakeID, Make 
      FROM MainTable 
      GROUP BY MakeID, Make) AS Make ON M.MakeMatch = Make.MakeID
LEFT JOIN MainTable Model ON M.MakeMatch = Model.MakeID AND M.ModelMatch = Model.ModelID
LEFT JOIN MainTable Color ON M.MakeMatch = Color.MakeID AND M.ColorMatch = Color.ColorID
LEFT JOIN MainTable Size ON M.MakeMatch = Size.MakeID AND M.SizeMatch = Size.SizeID

不需要案例陈述 - 只需简单的左连接。


原始回答

使用这样的案例陈述:

select a.val1,a.val2,b.val1,b.val2,..
from tableA a 
inner join tableB b 
on  CASE WHEN ISNULL(a.val1,0)=0 then b.val1 ELSE a.val1 END =b.val1
and CASE WHEN ISNULL(a.val2,0)=0 then b.val2 ELSE a.val2 END =b.val2
and CASE WHEN ISNULL(a.val3,0)=0 then b.val3 ELSE a.val3 END =b.val3
and CASE WHEN ISNULL(a.val4,0)=0 then b.val4 ELSE a.val4 END =b.val4
and (ISNULL(a.val1,0) <> 0 OR ISNULL(a.val2,0) <> 0 
  OR ISNULL(a.val3,0) <> 0 OR ISNULL(a.val4,0) <>0)
where a.description='ABC'