我有一个表,该表的一列的字符串格式如下:{1,4,5}
。它们可以是任意长度,我想将ID表与该ID在该字符串中的任何值连接起来。
这是第一张桌子
name id count
apple {1,3,6} 5
orange {5,3,1} 3
potato {8,1,9} 3
这是第二张表-
id2 category
1 foo
2 foobar
3 candy
4 candybar
5 oreo
6 pistachio
我想为第一个表中列出的每个ID都有一行,该ID具有第二个表中的类别。我希望他们看起来像这样-
id2 name id count
1 apple {1,3,6} 5
1 orange {5,3,1} 3
1 potato {8,1,9} 3
3 apple {1,3,6} 5
3 orange {5,3,1} 3
8 potato {8,1,9} 3
9 potato {8,1,9} 3
这是我到目前为止所掌握的。我可以使用一个join if the value is included
的联接过滤器吗?
select id2, name, id, count
from table2 as t2
left join table1 as t1
on t2.id2 %in% t1.id
答案 0 :(得分:4)
1)不请自来的建议
我认为值得考虑的是,数据库设计(即削减表的方式)是否真的对您的事业有利。当前表的设置方式违反了Codd的数据库设计1st Normal Form。考虑更改设计以表达FirstTable
和SecondTable
中的对象之间的n:m关系
在表的上下文中具有有效的名称。而不是在一个表中包含id2
,而在另一个表中包含id
,只需将两者都命名为id
。在查询中,您可以将它们称为firsttable.id
和secondtable.id
来区分它们。
2)实际答案
是的,有可能,但是(正如评论者所指出的)取决于您使用的数据库系统。
如果firststable.id
是PostgreSQL中的数组,则以下查询应起作用:
SELECT
*
FROM
first
JOIN
second
ON
second.id = ANY(first.ids);
-- Took the liberty to change the column names
此SQLFiddle提供了一个有效的示例。
如果firsttable.id
是字符串,则可以使用{{3,}中所述的'{42,23,17}':: int []将字符串转换为数组:
SELECT
*
FROM
first
JOIN
second
ON
second.id = ANY(first.ids::int[]);
如果是字符串,此here提供了一个有效的示例。
答案 1 :(得分:0)
刚开始解决此问题时,我没有看到PostgreSQL。
您可以尝试以下操作,但不能保证Postgre不具备所有功能。
SELECT * FROM (
SELECT
Split.a.value('.', 'VARCHAR(100)') AS ID2
,A.Name, A.ID, A.[Count]
FROM
(
SELECT Name, [Count], ID,
CAST ('<M>' + REPLACE(REPLACE(REPLACE(ID,'{',''),'}',''), ',', '</M><M>') + '</M>' AS XML) AS Data
FROM [StackOver].[dbo].[SplitKey]
) AS A CROSS APPLY Data.nodes ('/M') AS Split(a)
) as B
Left Join [StackOver].[dbo].[SplitKeyID2] as C
On B.ID2 = C.ID2
Where C.Category > ''
Order By B.ID2, B.name
答案 2 :(得分:0)
我非常相信,有一个更好的解决方案不涉及GROUP BY
和ARRAY_AGG()
,但是由于您已经在那儿,我想这个查询可以为您提供帮助:
select
t2.id2,
t2.category,
t1.id,
t1.count
from table1 t1
join table2 t2 on (
position ('{' || t2.id2 || '}' in t1.id) <> 0
or position ('{' || t2.id2 || ',' in t1.id) <> 0
or position (',' || t2.id2 || ',' in t1.id) <> 0
or position (',' || t2.id2 || '}' in t1.id) <> 0
)