在一个联接中匹配多个列

时间:2019-07-10 03:10:16

标签: sql join

我有两个表:

表1

item_name  |  assocID_1  |  assocID_2  |  assocID_3
ball            123           456           789

表2

assoc_key      assoc_value
123              red
456              white
789              blue

我可以创建以下内容的输出吗?

ball    red   white  blue

只有一个加入?我知道我可以多次连接表以轻松获得此结果,但是在我的实际表中,有超过3列,而且我正在使用的应用程序显然只能支持每个查询4个连接。

非常感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

如果您不关心性能,可以这样做:

select t1.item_name,
       max(case when t2.assoc_key = t1.assocID_1 then t2.assoc_value end),
       max(case when t2.assoc_key = t1.assocID_2 then t2.assoc_value end),
       max(case when t2.assoc_key = t1.assocID_3 then t2.assoc_value end)
from table1 t1 join
     table2 t2
     on t2.assoc_key in (t1.assocID_1, t1.assocID_2, t1.assocID_3)
group by t1.item_name;

您还可以使用子查询。如果我们假设table2中只有一个匹配的行:

select t1.item_name,
       (select t2.assoc_value from table2 t2 where t2.assoc_key = t1.assocID_1),
       (select t2.assoc_value from table2 t2 where t2.assoc_key = t1.assocID_2),
       (select t2.assoc_value from table2 t2 where t2.assoc_key = t1.assocID_3)
from table1 t1;

如果可以有多个匹配项,则可以使用聚合函数任意选择其中之一:

select t1.item_name,
       (select max(t2.assoc_value) from table2 t2 where t2.assoc_key = t1.assocID_1),
       (select max(t2.assoc_value) from table2 t2 where t2.assoc_key = t1.assocID_2),
       (select max(t2.assoc_value) from table2 t2 where t2.assoc_key = t1.assocID_3)
from table1 t1;

答案 1 :(得分:1)

我认为您不需要在这里加入。您只需要在SELECT语句中直接查找即可。这是 SQL Server 中的实现(在示例数据准备代码中,如果您使用的版本早于SQL Server 2016,请用相同的旧方法替换DROP TABLE IF EXISTS)

DDL和测试数据:

DROP TABLE IF EXISTS Table1
SELECT  item_name = 'ball'
        ,assocID_1 = 123
        ,assocID_2 = 456
        ,assocID_3 = 789
INTO    Table1   

DROP TABLE IF EXISTS Table2
SELECT  assoc_key       = 123
        ,assoc_value    = 'red'
INTO    Table2
UNION ALL
SELECT  assoc_key       = 456
        ,assoc_value    = 'white'
UNION ALL
SELECT  assoc_key       = 789
        ,assoc_value    = 'blue'

SELECT * FROM Table1
SELECT * FROM Table2

1。蛮力进取:

SELECT  item_name   = T1.item_name
        ,(SELECT TOP 1 assoc_value FROM Table2 WHERE assoc_key = T1.assocID_1)
        ,(SELECT TOP 1 assoc_value FROM Table2 WHERE assoc_key = T1.assocID_2)
        ,(SELECT TOP 1 assoc_value FROM Table2 WHERE assoc_key = T1.assocID_3)
FROM    Table1 T1

2。动态构建轻松查询,然后执行它。通过这种方法,不必担心列数:

DECLARE @SQL NVARCHAR(MAX) = 'SELECT    item_name   = T1.item_name '

SELECT  @SQL += '
,(SELECT TOP 1 assoc_value FROM Table2 WHERE assoc_key = T1.'+COLUMN_NAME+')'
FROM    INFORMATION_SCHEMA.COLUMNS
WHERE   TABLE_SCHEMA = 'dbo'  -- provide your proper schema name here
AND     TABLE_NAME = 'Table1'
AND     COLUMN_NAME <> 'item_name' -- provide the columns you want to avoid doing lookups
ORDER   BY ORDINAL_POSITION

SET     @SQL+='
FROM    Table1 T1 '

PRINT   @SQL

EXEC    sp_executesql @statement=@SQL

3。 UNPIVOT,JOIN和PIVOT的组合

SELECT  item_name, [assocID_1], [assocID_2], [assocID_3]  -- you can dynamically build the select list like above example if you need
FROM    
        (
            SELECT  IQ.item_name, IQ.assocId, T2.assoc_value
            FROM    (
                        SELECT  UNP.item_name, UNP.assocId, UNP.Value
                        FROM    Table1 T1
                        UNPIVOT
                        (
                                Value FOR assocId IN ([assocId_1], [assocId_2], [assocId_3]) -- you can dynamically build this column list like above example if you need

                        ) UNP
                    ) IQ
                    INNER JOIN Table2 T2
                        ON IQ.Value = T2.assoc_key
        ) OQ
PIVOT
(
        MAX(assoc_value)
        FOR associd IN ([assocID_1], [assocID_2], [assocID_3]) -- you can dynamically build this column list like above example if you need
) PV

答案 2 :(得分:0)

select item_name, decode(ASSOCID_1,(select assocID_1 from t1  ), (select assoc from t2 where assoc_key =aa.assocID_1),null ) ,
                                    decode(ASSOCID_2,(select assocID_2 from t1  )  , (select assoc from t2 where assoc_key =aa.assocID_1),null ),
                                    decode(ASSOCID_3,(select assocID_3 from t1  ), (select assoc from t2 where assoc_key =aa.assocID_1),null ) from t1 aa