【问题标题】:SQL JOIN values to ARRAY to create another ARRAY fieldSQL JOIN 值到 ARRAY 以创建另一个 ARRAY 字段
【发布时间】:2020-08-21 23:22:27
【问题描述】:

也许我的搜索很差,但我在任何地方都找不到这个问题或答案。

假设我有一个像 CLASSROOM 这样的桌子:

[ { teacher_id: T1,
    students: [S11, S12, S13]},
  { teacher_id: T2,
     students: [S21, S22, S23]}]

“学生”字段是一个学生 ID 的数组。还有一个表 STUDENTS 像:

[ { id: S11, name: "Aaron"}, { id: S12, name: "Bob"}, { id: S13, name: "Charlie"},
  { id: S21, name: "Amy"}, { id: S22, name: "Becky"}, { id: S23, name: "Cat"} ]

我想创建具有如下行的输出表:

[ { teacher_id: T1,
    students: [S11, S12, S13 ],
    names: [ "Aaron", "Bob", "Charlie" ] },
  { teacher_id: T2,
    students: [S21, S22, S23 ],
    names: [ "Amy", "Becky", "Cat" ] } ]

(是的,这个例子很傻,但我不想让你厌烦我的情况。)

我想我可以 FLATTEN CLASSROOM 表,然后进行直接连接,但我的真实表足够大且足够复杂,如果可以的话,我想避免它。有没有更好的办法?

注意:假设学生可以在多个班级。老师 (teacher_id) 是独一无二的。

【问题讨论】:

  • 请用您正在运行的数据库标记您的问题:postgresql、mysql、oracle...?
  • 我不明白你在这里使用数组表示法。从字面上看,您的 CLASSROOM 表似乎总是有一行,其中包含一个数组值(可能具有 ARRAY 或 VARIANT 的数据类型),因为您的示例是 "[ { teacher_id: T1, students: [S11 ,S12,S13]},{教师ID:T2,学生:[S21,S22,S23]}]"。您的 STUDENTS 表也是如此。这是你想要传达的吗?或者您的意思是说您的 CLASSROOM 表中有 2 行,每行都有一个字典值?
  • 感谢您的阅读。 CLASSROOM 表有两个字段:“teacher_id”和“students”(一个数组);它有 2 行。 STUDENTS表2个字段:“id”和“name”;它有 6 行。所需的输出表将有 2 行(如 CLASSROOM),但第三列称为“名称”,它也是一个数组。
  • 为了清楚起见,这里是用于构建示例表的 Snowflake 语法:create table CLASSROOM (teacher_id VARCHAR, students ARRAY); insert into CLASSROOM select $1, parse_json($2) from values ('T1','["S11","S12","S13"]'),('T2','["S21","S22","S23"]'); create table STUDENTS (id VARCHAR, name VARCHAR); insert into STUDENTS values ('S11','Aaron'),('S12','Bob'),('S13','Charlie'),('S21','Amy'),('S22','Becky'),('S23','Cat');

标签: sql arrays json join snowflake-cloud-data-platform


【解决方案1】:

这个想法是展平数组并重新聚合。我不是 100% 确定 Snowflake 中的语法,但我认为这会起作用:

select c.*,
       (select array_agg(ss.name) within group (order by s.index) as student_names
        from table(flatten(input => c.students, mode => 'array')) s join
             students ss
             on ss.id = s.value
       ) as names
from classroom c;

【讨论】:

  • 谢谢!让我深思熟虑,但使用 Snowflake,我收到“SQL 编译错误:无法评估不支持的子查询类型”。还有什么建议吗?
【解决方案2】:

基于https://stackoverflow.com/users/1144035/gordon-linoff,我得到以下在雪花中工作:

create table CLASSROOM (teacher_id  VARCHAR, students  ARRAY);
insert into CLASSROOM select $1, parse_json($2) 
from values ('T1','["S11","S12","S13"]'),('T2','["S21","S22","S23"]');

create table STUDENTS (id VARCHAR, name VARCHAR);
insert into STUDENTS values ('S11','Aaron'),('S12','Bob'),('S13','Charlie'),('S21','Amy'),('S22','Becky'),('S23','Cat');

select teacher_id, 
    array_agg(s.value::String) as student_ids, 
    array_agg(ss.name) as student_names
from CLASSROOM, table(flatten(input => CLASSROOM.students, mode => 'array')) s 
join STUDENTS ss on ss.id = s.value
group by teacher_id, s.SEQ
order by teacher_id;

【讨论】:

  • 能否请您粘贴 DDL 和插入语句以准备表格和数据。
猜你喜欢
  • 2016-01-16
  • 2020-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-07
  • 1970-01-01
相关资源
最近更新 更多