我在工作中遇到一个问题,我对SQL或一般的数据库知之甚少,以至于甚至不知道如何搜索。
因此,在对StackOverflow问题进行了无数次“观看”之后,这是我的第一个问题。
我有两个表,彼此之间没有其他关系,除了同一组列(我将它们称为item_1至item_3)之外,它们中的值以随机顺序排列。 我需要连接这些表,但是我不能只将它们连接到每一列,因为我正在寻找组相同的项目任何顺序。 两个表中的集合必须相同(没有更多,没有更少),但位置无关紧要。
这里有一些虚拟表(希望)解释我的意思:
表1
user_id | use_name | item_1 | item_2 | item_3
--------+----------+--------+--------+--------
1 | Tim | A | B | NULL
2 | Tom | NULL | NULL | C
3 | Sam | A | NULL | NULL
table2
role | item_1 | item_2 | item_3
---------+--------+--------+--------
type1 | A | NULL | B
type2 | A | B | C
type3 | A | NULL | NULL
我正在寻找一个选择/联接,它会产生一个这样的表:
user_name | role
----------+------
Tim | type1
Sam | type3
我尝试了一个排列表,但在实际情况中,我们不是在考虑3列而是10列,这似乎不是最好的解决方案。 我目前正在尝试通过枢轴/枢轴实现一些有用的操作,但到目前为止没有任何结果。
我什至只对文章链接感到非常满意。甚至是我遇到的问题的独特名称,我都可以用Google搜索:)
非常感谢您!
答案 0 :(得分:1)
如果我的理解正确,那么您希望各行之间完全匹配,其中各项需要完全匹配。
您的数据模型较差。在数据库中,不应将重复的值存储在列中。相反,您应该将它们存储在行中。
但是,取消数据透视很简单:
with t1 as (
select t1.*, v.item,
count(*) over (partition by user_id) as cnt
from table1 t1 cross apply
(values (t1.item_1), (t1.item_2), (t1.item_3)
) v(item)
where v.item is not null
),
t2 as (
select t2.*, v.item,
count(*) over (partition by role) as cnt
from table2 t2 cross apply
(values (t2.item_1), (t2.item_2), (t2.item_3)
) v(item)
where v.item is not null
)
select t1.user_id, t1.user_name, t2.role
from t1 join
t2
on t1.item = t2.item and t1.cnt = t2.cnt
group by t1.user_id, t1.user_name, t2.role, t1.cnt
having count(*) = t1.cnt;