我在postgresql中有两个表,其中包含json数组列tableA.B
和tableB.B
。如何在这些json列上连接这些表?
即
select tableA.id, tablA.A, tableB.id,tableA.B, tableB.name
from tableA, tableB
where tableA.B = tableB.B
--tableA--
id | A | B
1 | 36464 | ["874746", "474657"]
2 | 36465 | ["874748"]
3 | 36466 | ["874736", "474654"]
--tableB--
id | name | B
1 | john | ["8740246", "2474657"]
2 | mary | ["874748","874736"]
3 | clara | ["874736", "474654"]
答案 0 :(得分:3)
实际上,对于 Postgres 9.4 或更高版本中的数据类型 jsonb
,这将变为死简单。您的查询将起作用(丑陋的命名约定,输出中的代码和重复名称除外)。
CREATE TEMP TABLE table_a(a_id int, a int, b jsonb);
INSERT INTO table_a VALUES
(1, 36464, '["874746", "474657"]')
, (2, 36465, '["874748"]')
, (3, 36466, '["874736", "474654"]');
CREATE TEMP TABLE table_b(b_id int, name text, b jsonb);
INSERT INTO table_b VALUES
(1, 'john' , '["8740246", "2474657"]')
, (2, 'mary' , '["874748","874736"]')
, (3, 'clara', '["874736", "474654"]');
查询:
SELECT a_id, a, b.*
FROM table_a a
JOIN table_b b USING (b); -- match on the whole jsonb column
您甚至要求表明您正在使用数据类型json
,其中不存在相等运算符:
你刚才没有提到最重要的细节。
显而易见的解决方案是切换到jsonb
。
是否可以将b压缩为新行而不是数组?
在LATERAL
加入中使用jsonb_array_elements(jsonb)
or jsonb_array_elements_text(jsonb)
:
SELECT a_id, a, b.b_id, b.name, b_array_element
FROM table_a a
JOIN table_b b USING (b)
, jsonb_array_elements_text(b) b_array_element
这仅返回整个数组上匹配的行。关于LATERAL
:
如果您想匹配数组元素,请在加入之前取消您的数组。
整个设置似乎迫切需要normalization。
答案 1 :(得分:0)
WITH tableA AS
(SELECT 1 AS id,
36464 AS A,
'["874746", "474657"]'::jsonb AS B
UNION SELECT 2 AS id,
36465 AS A,
'["874748"]'::jsonb AS B
UNION SELECT 3 AS id,
36466 AS A,
'["874736", "474654"]'::jsonb AS B),
tableB AS
( SELECT 1 AS id,
'john' AS name,
'["8740246", "2474657"]'::jsonb AS B
UNION SELECT 2 AS id,
'mary' AS name,
'["874748", "874736"]'::jsonb AS B
UNION SELECT 3 AS id,
'clara' AS name,
'["874736", "474654"]'::jsonb AS B)
SELECT *
FROM tableA
inner join tableB using(B);
给你
b | id | a | id | name
----------------------+----+-------+----+-------
["874736", "474654"] | 3 | 36466 | 3 | clara
这不是你所期望的吗?