3

我需要连接两个表以根据 Reason_Id 从另一个表中获取多个字段的 Reason_Descriptions。我的问题是我不确定如何比较字段值。

Table 1:
  Reason_Id,
  Reason_Description


Table 2:
  Reason1_Id,
  Reason2_Id,
  Reason3_Id

表 2 字段中的值始终与表 1 中的 Reason_Id 字段中的值匹配。我只需要显示描述而不是 ID。任何帮助表示赞赏。我知道如何在一个表字段与另一个表字段匹配的情况下进行简单的连接,但在这种情况下,表 2 中的每个原因 1、2、3 将具有不同的原因 ID 以匹配表 1。

4

6 回答 6

2

您必须加入描述表三次,表 2 中的每个字段一次。

例如:

SELECT Desc1.Reason_Description AS Reason1_Description, 
       Desc2.Reason_Description AS Reason2_Description, 
       Desc3.Reason_Description AS Reason3_Description 
FROM Table2
JOIN Table1 Desc1 ON Table2.Reason1_Id = Desc1.Reason_Id
JOIN Table1 Desc2 ON Table2.Reason2_Id = Desc2.Reason_Id
JOIN Table1 Desc3 ON Table2.Reason3_Id = Desc3.Reason_Id
于 2012-11-29T20:50:10.703 回答
0
select * from t1 inner join t2 
 on t1.Reason_Id = t2.Reason1_Id
    or t1.Reason_Id = t2.Reason2_Id
    or t1.Reason_Id = t2.Reason3_Id

看看这里http://sqlfiddle.com/#!3/3b9d1/2

于 2012-11-29T20:51:18.627 回答
0
select Reason_Description
from table1 a
Inner join table2 b
  On a.Reason_id = b.Reason1_Id
Union
select Reason_Description
from table1 a
Inner join table2 b
  On a.Reason_id = b.Reason2_Id
Union
select Reason_Description
from table1 a
Inner join table2 b
  On a.Reason_id = b.Reason3_Id
于 2012-11-29T20:52:31.357 回答
0

您基本上可以UNPIVOT使用第二个表,然后加入这些值。如果您没有UNPIVOT功能,则可以使用UNION ALL

select t1.reason_description, t2.col
from table1 t1
left join
(
  select reason1_id value, 't2_reason1_id' col
  from table2
  union all
  select reason2_id value, 't2_reason2_id' col
  from table2
  union all
  select reason3_id value, 't2_reason3_id' col
  from table2
) t2
  on t1.reason_id = t2.value

如果你有UNPIVOT,那么你可以使用这样的东西:

select t1.reason_description
from table1 t1
(
  select value, col
  from table2
  unpivot
  (
    value for col in (reason1_id, reason2_id, reason3_id)
  ) un
) t2
  on t1.reason_id = t2.value
于 2012-11-29T20:54:59.807 回答
0

我们在我的办公室做了很多这样的过程。如果您具有基于安全性和服务器级别的能力,请使用功能。处理器迭代的成本可能更高,但如果您没有庞大的表(我们使用多达数百万条记录进行此操作),则内联标量函数可以生成干净的代码

CREATE FUNCTION dbo.fnc_GetReasonDesc (@ReasonId as int) RETURNS varchar(50) AS
  BEGIN
    DECLARE @rDesc as varchar(50)
    SElECT @rDesc = Reason_Description From Table2 WHERE Reason_id = @ReasonId
    RETuRN @rDesc
  END

Select dbo.fnc_GetReasondesc(Reason1_Id), dbo.fnc_GetReasonDesc(Reason2_Id), ...

最大的优势是,无论您必须使用多少个 Id 字段或它们可能位于多少个不同的表中,您始终可以使用相同的函数将 id 转换为 desc。您还可以创建一个枚举表并包含一个“描述类型”,这样如果您有说明原因描述以及问题描述或活动描述等,您可以在“描述”表中添加一个附加字段,例如 descriptionType ,然后将该值包含在您的函数参数中。现在,同一个表和函数可以处理您可能需要的任意数量的不同枚举数。

希望这可以帮助

于 2012-11-29T21:05:58.617 回答
0

我相信这个版本对于大表应该更有效,因为它只需要通过 Table1 而不是 3:

如果它具有学术兴趣,请在此处留下答案,但它的性能比多重连接选项差,所以请不要使用这个:

if OBJECT_ID('Table2') is not null drop table Table2
if OBJECT_ID('Table1') is not null drop table Table1


create table Table1
(
  Reason_Id bigint not null identity(1,1) primary key clustered
  , Reason_Description nvarchar(256)
)
create table Table2
(
    Id bigint not null identity(1,1) primary key clustered
  , Reason1_Id bigint foreign key references Table1(Reason_Id)
  , Reason2_Id bigint foreign key references Table1(Reason_Id)
  , Reason3_Id bigint foreign key references Table1(Reason_Id)
)
insert Table1 select 'Desc 1'
insert Table1 select 'Desc 2'
insert Table1 select 'Desc 3'
insert Table1 select 'Desc 4'

insert Table2 select 1, 2, 3
insert Table2 select 4, 4, 4

select a.id 
, max(case when a.Reason1_Id = b.Reason_Id then b.Reason_Description end)
, max(case when a.Reason2_Id = b.Reason_Id then b.Reason_Description end)
, max(case when a.Reason3_Id = b.Reason_Id then b.Reason_Description end)
from Table2 a
left outer join Table1 b --could do an inner join but left outer is safer
on b.Reason_Id in (a.Reason1_Id, a.Reason2_Id, a.Reason3_Id)
group by a.Id 

这是一个 SQL Fiddle 链接,将上述内容与多表连接选项进行比较:http ://sqlfiddle.com/#!3/1f5e6/1

于 2012-11-29T21:06:49.657 回答