如何根据列标题名称执行查找?

时间:2021-01-18 00:17:20

标签: sql-server tsql pivot

希望有人可以协助构建以下查询。

代码类型

Code |  ID  | Type
---------------------
ABC  | 1234 | 'Type1'
ABC  | 1234 | 'Type2'
CDE  | 2345 | 'Type1'
CDE  | 2345 | 'Type3'
EFG  | 3456 | 'Type2'

类型值

Code |  ID  |  Type1  |  Type2  |  Type3
----------------------------------------
ABC  | 1234 | ';kjap' | ')&jaa' | '123ja' 
CDE  | 2345 |   NULL  | '$@#$a' | 'asdfa'
EFG  | 3456 | '&*(01' | 'jmblk' |   NULL

我希望能够构建尾随列“TypeValue”,它本质上是基于 CodeIDTypeValues 表中查找特定 {{1} }.

Type

2 个答案:

答案 0 :(得分:2)

您可以使用 CASE 来选择要使用的列。例如:

select
  t.*,
  case when t.type = 'Type1' then v.type1
       when t.type = 'Type2' then v.type2
       when t.type = 'Type3' then v.type3
  end as typevalue
from codetypes t
join typevalues v on v.code = t.code and v.id = t.id

根据 HABO 的评论进行编辑

查询可以进一步简化为:

select
  t.*,
  case t.type when 'Type1' then v.type1
              when 'Type2' then v.type2
              when 'Type3' then v.type3
  end as typevalue
from codetypes t
join typevalues v on v.code = t.code and v.id = t.id

答案 1 :(得分:2)

首先:如果你可以改变设计,你应该这样做。每当您觉得需要 name-number 列(Type1、Type2...)时,这都是糟糕的设计。

正在寻找一种完全通用的方法,您可以尝试一下:

DECLARE @CodeTypes TABLE(Code VARCHAR(100),ID INT,[Type] VARCHAR(100));
DECLARE @TypeValues TABLE(Code VARCHAR(100),ID INT,Type1 VARCHAR(100),Type2 VARCHAR(100),Type3 VARCHAR(100))

INSERT INTO @CodeTypes(Code,ID,[Type]) VALUES
 ('ABC',1234,'Type1')
,('ABC',1234,'Type2')
,('CDE',2345,'Type1')
,('CDE',2345,'Type3')
,('EFG',3456,'Type2');

INSERT INTO @TypeValues(Code,ID,Type1,Type2,Type3) VALUES
 ('ABC',1234,';kjap',')&jaa','123ja') 
,('CDE',2345,  NULL ,'$@#$a','asdfa')
,('EFG',3456,'&*(01','jmblk',  NULL );

--查询

SELECT ct.Code
      ,ct.ID,ct.[Type]
      ,(SELECT tv.* FOR XML PATH(''),TYPE)
       .value('(*[local-name()=sql:column("Type")]/text())[1]','varchar(100)') TypeValue  
FROM @CodeTypes ct
INNER JOIN @TypeValues tv ON ct.ID=tv.ID
                         AND ct.Code=tv.Code;

简单的想法:

  • 我们使用简单的 JOIN 将两个表放在一起。
  • 神奇之处在于 XML 能够按名称抓取列。
  • 我们为结果集的每一行查询一行tv
  • 我们为该行创建一个 XML,并通过 local-name() 谓词选择一个值。

提示:这不会很快,但是 - 如果您决定添加 Type4,您将不必重写现有查询...