【问题标题】:PostgreSQL JOIN with array type with array elements order, how to implement?PostgreSQL JOIN with array type with array elements order,如何实现?
【发布时间】:2011-01-30 00:18:25
【问题描述】:

我在数据库中有两个表:

CREATE TABLE items(
 id SERIAL PRIMARY KEY,
 ... some other fields
);

此表包含具有唯一 ID 的数据行。

CREATE TABLE some_chosen_data_in_order(
 id SERIAL PRIMARY KEY,
 id_items INTEGER[],
);

此表包含数组类型字段。每行包含表items 中的ID 值,按特定顺序排列。例如:{2,4,233,5}

现在,我想从表 items 中获取数据,以获取表 some_chosen_data_in_order 中所选行的数据,其中包含数组类型中元素的顺序。

我的尝试是加入:

SELECT I.* FROM items AS I 
JOIN some_chosen_data_in_order AS S ON I.id = ANY(S.id_items) WHERE S.id = ?

第二次尝试是子查询:

SELECT I.* FROM items AS I 
WHERE I.id = ANY 
(ARRAY[SELECT S.id_items FROM some_chosen_data_in_order  WHERE id = ?])

但它们都没有按照数组字段中的顺序保持 ID。您能帮我吗,如何从items 表中获取与特定行的some_chosen_data_in_order 表中的数组ID 顺序相对应的数据?

【问题讨论】:

    标签: sql arrays postgresql join


    【解决方案1】:
    SELECT t.*
    FROM unnest(ARRAY[1,2,3,2,3,5]) item_id
    LEFT JOIN items t on t.id=item_id
    

    上面的查询从items表中选择ids:1,2,3,2,3,5的项目。

    【讨论】:

    • unnest() 是一个非常酷的技巧!我有一份来自客户的 ID 列表,需要加入他们的行列,但我想找到一种不使用临时表的方法。您可以加入 (select unnest(ARRAY[1,2,3])) 作为 idlist,它就像一个冠军。谢谢!
    • @apinstein 你能告诉我查询吗?还是没弄明白
    • 如果你想连接两个表,你可以使用SELECT b.*, a.item_id FROM (SELECT unnest(array_column_in_table_a) item_id FROM table_a) as a RIGHT JOIN table_b b on b.id=a.item_id;
    • 我需要加入表格,但上面的评论对我不起作用,但这样做了:SELECT * FROM table_a a JOIN table_b b ON b.id = ANY(a.array_column_in_table_a);,感谢garysieling.com/blog/postgres-join-on-an-array-field
    • 这与问题不符,为什么选择它?
    【解决方案2】:

    我能给你的最好的建议是规范化你的表。

    int_array contrib 模块有一个 idx 函数,可以为您提供 int 在数组中的索引位置。 snippets wiki 上还有一个 idx 函数,适用于任何数据类型的数组。

    SELECT i.*, idx(id_items, i.id) AS idx
    FROM some_chosen_data_in_order s
    JOIN items i ON i.id = ANY(s.id_items)
    ORDER BY idx(id_items, i.id)
    

    【讨论】:

    • 这显然是我需要的。谢谢!由于效率原因,我正在对我的数据库进行非规范化。
    • 工作,谢谢。 order by 子句也仅适用于 idx
    • where s.id = ? -- 一个身份证号码
    【解决方案3】:
    select distinct on (some_chosen_data_in_order.id)
      some_chosen_data_in_order.*,
       array_to_json( array_agg(row_to_json( items))
      over ( partition by some_chosen_data_in_order.id ))
    from some_chosen_data_in_order
      left join items on items.id = any (some_chosen_data_in_order.id_items)
    

    【讨论】:

      【解决方案4】:
      SELECT I.* FROM items AS I 
      WHERE I.id IN (SELECT UNNEST(id_items) FROM some_chosen_data_in_order 
      (ARRAY[SELECT S.id_items FROM some_chosen_data_in_order  WHERE id = ?])
      

      【讨论】:

      • 添加代码作为答案时,请为您的答案添加一点解释,以供将来的读者阅读。
      【解决方案5】:

      如果你不喜欢函数 (https://stackoverflow.com/a/2489805/642096):

      SELECT jt.*
      FROM (
           SELECT ARRAY_AGG(DISTINCT dupes_column) AS unique_vals
           FROM dupes_table
      ) q
      LEFT JOIN joined_table jt
      ON jt.id = ANY(q.unique_vals);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-09
        • 1970-01-01
        • 2019-09-03
        • 2017-03-01
        • 2022-12-01
        • 2012-12-15
        • 1970-01-01
        • 2019-03-27
        相关资源
        最近更新 更多