简体   繁体   中英

Fetch specific column and row data based on row values from another table in SQL server

Does anyone know if it is possible to fetch data from a column in a table based on row values from another table?

eg

Table 1:

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

Table 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

I need to match the date but bring through the correct letter for each name

So Table 3 would be:

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

Any suggestions are welcome.

thanks

If you are looking for way without column hardcodes, you can try this. Lets your tables has names @table1, @table2 . Then:

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]);

There are many ways to achieve the desired output. My solution uses a combination of cursors and dynamic TSQL.

Here is the code, commented step by step:

--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

Here are the results. The first two tables show the inputs, the third table contains the actual results:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM