Sql 将具有字典的表连接到不同表中的唯一id列
我有两个表,Sql 将具有字典的表连接到不同表中的唯一id列,sql,Sql,我有两个表,表A和表B,我试图从中提取信息并创建一个结果表 Table A user_ids value {user_123, user_234} apples {user_456, user_123} oranges {user_234} kiwi 我希望以一种将导致以下结果的方式连接这两个表: Table C user_ids value user_names {user_123, use
表A
和表B
,我试图从中提取信息并创建一个结果表
Table A
user_ids value
{user_123, user_234} apples
{user_456, user_123} oranges
{user_234} kiwi
我希望以一种将导致以下结果的方式连接这两个表:
Table C
user_ids value user_names
{user_123, user_234} apples {John Smith, Jane Doe}
{user_456, user_123} oranges {John Doe, John Smith}
{user_234} kiwi {Jane Doe}
任何帮助都将不胜感激 其他人已经鼓励您规范化您的设计,并且有许多帖子介绍了为什么建议这样做。使用您当前的共享数据集,使用postgres完成以下操作,
user\u id
被视为文本数组。我还使用user\u id
astext
as-usedcast(user\u id as text[])
进行了测试,以将其转换为text
数组
请参见下面的小提琴和结果:
模式(PostgreSQL v11)
第一个CTE
user\u values
为每个user\u id
和值创建一行。第二个CTEmerged_值
连接模式user_
上的table_b
(如果存在),并使用DISTINCT
确保唯一的结果。最终投影基于值和用户array\u agg
进行分组,以将所有user\u id
或names
收集到一行中
查询#1
CREATE TABLE table_a (
"user_ids" text[],
"value" VARCHAR(7)
);
INSERT INTO table_a
("user_ids", "value")
VALUES
('{user_123, user_234}', 'apples'),
('{user_456, user_123}', 'oranges'),
('{user_234}', 'kiwi');
CREATE TABLE table_b (
"id" INTEGER,
"name" VARCHAR(10)
);
INSERT INTO table_b
("id", "name")
VALUES
('123', 'John Smith'),
('234', 'Jane Doe'),
('456', 'John Doe');
WITH user_values AS (
SELECT
unnest(a.user_ids) user_id,
a.value
FROM
table_a a
),
merged_values AS (
SELECT DISTINCT
a.user_id,
a.value,
b.name
FROM
user_values a
LEFT JOIN
table_b b ON a.user_id = CONCAT('user_',b.id)
)
SELECT
array_agg(user_id) user_ids,
value,
array_agg(name) "names"
FROM
merged_values
GROUP BY
value;
用户识别码
价值
名字
用户_123,用户_456
橘子
约翰·史密斯,无名氏
用户_123,用户_234
苹果
约翰·史密斯,无名氏
用户_234
几维鸟
无名氏
请将您的数据库设计至少规范化为3NF。你的设计破坏了1NF。只标记你真正使用的一个DBMS。除此之外,正如@TheImpler所写的(尽管你已经违反了第一个NF),规范化你的模式。请参阅(扰流板:是的)。@stickybit用户ID可能是一个数组列,因此它没有“列中的CSV”反模式那么糟糕。@muistooshort:除非数组是DBMS所关注的原子单元,否则它仍然违反了第一个NF。但事实并非如此,我们可以清楚地看到。因此,它仍然很糟糕(足够了),(简单的)外键约束是不可能的,这使得查询数据比需要的更复杂。
WITH user_values AS (
SELECT
unnest(a.user_ids) user_id,
a.value
FROM
table_a a
),
merged_values AS (
SELECT DISTINCT
a.user_id,
a.value,
b.name
FROM
user_values a
LEFT JOIN
table_b b ON a.user_id = CONCAT('user_',b.id)
)
SELECT
array_agg(user_id) user_ids,
value,
array_agg(name) "names"
FROM
merged_values
GROUP BY
value;