根据SQL Server中另一个表的行值获取特定的列和行数据

时间:2017-01-31 14:19:42

标签: sql sql-server

有没有人知道是否可以根据另一个表中的行值从表中的列中获取数据?

e.g。

表1:

Name| Date 
----|-----
Bob | D1
Jon | D2
Stu | D3
Amy | D4

表2:

Date |Bob |Jon |Stu |Amy
-----|----|----|----|----
D1   | A  | B  | C  | D
D2   | B  | C  | D  | A
D3   | C  | D  | A  | B
D4   | D  | A  | B  | C

我需要匹配日期,但为每个名字带来正确的字母

所以表3将是:

Name| Date | Letter
----|------|-------
Bob | D1   | A
Jon | D2   | C
Stu | D3   | A
Amy | D4   | C

欢迎任何建议。

感谢

2 个答案:

答案 0 :(得分:1)

如果您正在寻找没有列硬编码的方法,您可以试试这个。 让您的表格的名称为 @ table1,@ table2 。然后:

select 
     [Name]     = [t1].[Name]
    ,[Date]     = [t1].[Date]   
    ,[Letter]   = [col2].[value]('.', 'varchar(10)')    
from 
    @table1 as [t1]
cross apply
    (
        select [t2_xml] = cast((select * from @table2 for xml path('t2'))  as xml)
    ) as [t2]
cross apply  
    [t2].[t2_xml].[nodes]('t2[Date/text()=sql:column("[t1].[Date]")]') as [tab]([col])
cross apply  
    [col].[nodes]('*[local-name(.)=sql:column("[t1].[Name]")]') as [tab2]([col2]);

答案 1 :(得分:0)

有很多方法可以实现所需的输出。我的解决方案使用游标和动态TSQL的组合。

这是代码,一步一步评论:

--1. create test tables
create table table1 ([Name] nvarchar(50),[Date] nvarchar(50))
create table table2 ([Date] nvarchar(50),Bob nvarchar(50),Jon nvarchar(50),Stu nvarchar(50),Amy nvarchar(50))
create table table3 ([Name] nvarchar(50),[Date] nvarchar(50),[Letter] nvarchar(50))

--2. populate test tables
insert into table1
          select 'Bob','D1'
union all select 'Jon','D2'
union all select 'Stu','D3'
union all select 'Amy','D4'

insert into table2
          select 'D1','A','B','C','D'
union all select 'D2','B','C','D','A'
union all select 'D3','C','D','A','B'
union all select 'D4','D','A','B','C'

--3. declare variables
DECLARE @query      NVARCHAR(max);   --this variable will hold the dynamic TSQL query
DECLARE @name       NVARCHAR(50);
DECLARE @date       NVARCHAR(50);
DECLARE @result     NVARCHAR(50)     --this variable will hold "letter" value returned by dynamic TSQL query
DECLARE @testCursor CURSOR;

--4. define the cursor that will scan all rows in table1
SET @testCursor = CURSOR FOR SELECT [Name], [Date] FROM table1;

OPEN @testCursor;
    FETCH NEXT FROM @testCursor INTO @name, @date;
    WHILE @@FETCH_STATUS = 0
        BEGIN
            --5. for each row in table 1 create a dynamic query that retrieves the correct "Letter" value from table2
            set @query = 'select @res=' + @name + ' from table2 where [Date] =''' + @date +''''

            --6. executes dynamic TSQL query saving result in @result variable
            EXECUTE sp_executesql @query, N'@res nvarchar(50) OUTPUT', @res=@result OUTPUT

            --inserts data in table3 that holds final results
            insert into table3 select @name, @date, @result

            FETCH NEXT FROM @testCursor INTO  @name, @date;
        END
CLOSE @testCursor;
DEALLOCATE @testCursor;

select * from table1  
select * from table2
select * from table3

以下是结果。前两个表显示输入,第三个表包含实际结果:

enter image description here