如果连接键具有特定字段,是否可以创建一个连接条件?

时间:2019-03-19 22:43:57

标签: sql postgresql

我有一个表,该表的一列的字符串格式如下:{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

3 个答案:

答案 0 :(得分:4)

1)不请自来的建议

  • 我认为值得考虑的是,数据库设计(即削减表的方式)是否真的对您的事业有利。当前表的设置方式违反了Codd的数据库设计1st Normal Form。考虑更改设计以表达FirstTableSecondTable中的对象之间的n:m关系

  • 在表的上下文中具有有效的名称。而不是在一个表中包含id2,而在另一个表中包含id,只需将两者都命名为id。在查询中,您可以将它们称为firsttable.idsecondtable.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 BYARRAY_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
)