我有一个看起来像这样的表:
CREATE TABLE tracks (id SERIAL, artists JSON);
INSERT INTO tracks (id, artists)
VALUES (1, '[{"name": "blink-182"}]');
INSERT INTO tracks (id, artists)
VALUES (2, '[{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]');
Run Code Online (Sandbox Code Playgroud)
还有其他几个与此问题无关的列.将它们存储为JSON是有原因的.
我要做的是查找具有特定艺术家姓名(完全匹配)的曲目.
我正在使用此查询:
SELECT * FROM tracks
WHERE 'ARTIST NAME' IN
(SELECT value->>'name' FROM json_array_elements(artists))
Run Code Online (Sandbox Code Playgroud)
例如
SELECT * FROM tracks
WHERE 'The Dirty Heads' IN
(SELECT value->>'name' FROM json_array_elements(artists))
Run Code Online (Sandbox Code Playgroud)
但是,这会进行全表扫描,并且速度不是很快.我尝试使用函数创建GIN索引names_as_array(artists)并使用'ARTIST NAME' = ANY names_as_array(artists),但是不使用索引并且查询实际上明显更慢.
当我有一个具有分隔值的列时,我可以使用该unnest()函数:
myTable
id | elements
---+------------
1 |ab,cd,efg,hi
2 |jk,lm,no,pq
3 |rstuv,wxyz
select id, unnest(string_to_array(elements, ',')) AS elem
from myTable
id | elem
---+-----
1 | ab
1 | cd
1 | efg
1 | hi
2 | jk
...
Run Code Online (Sandbox Code Playgroud)
我如何包含元素编号?即:
id | elem | nr
---+------+---
1 | ab | 1
1 | cd | 2
1 | efg | 3
1 | hi | 4
2 | jk | 1
...
Run Code Online (Sandbox Code Playgroud)
我想要源字符串中每个元素的原始位置.我试着窗口函数(row_number(), …
sql arrays postgresql window-functions set-returning-functions
我有一张桌子bank_accounts:
Column | Type | Modifiers | Storage | Stats target | Description
---------------+-----------------------+-------------------------------------------------------------------------+----------+--------------+-------------
id | integer | not null default nextval('bank_accounts_id_seq'::regclass) | plain | |
name | character varying(50) | | extended | |
bank_accounts | jsonb | not null | extended | |
Run Code Online (Sandbox Code Playgroud)
它在jsonb列中有一些 JSON :
id | name | bank_accounts
----+-------+--------------------------------------------------------------------------
1 | test1 | [{"name": "acct1", "balance": -500}, {"name": "acct2", "balance": -300}]
Run Code Online (Sandbox Code Playgroud)
我正在使用 jsonb_array_elements 获取一个用户的帐户列表:
select jsonb_array_elements(bank_accounts)->>'name' as name, jsonb_array_elements(bank_accounts)->>'balance' as balance …Run Code Online (Sandbox Code Playgroud) 这是plpgsql 函数的一个变体,它返回多个列,并被多次调用。然而,我希望找到针对我的特殊情况的解决方案。
我有一个函数,它处理具有给定参数的行数组,并返回一组行+一个新列。
CREATE OR REPLACE foo(data data[], parameter int) RETURNS SETOF enhanceddata AS
...
Run Code Online (Sandbox Code Playgroud)
该函数适用于只有一组数据的测试用例
SELECT * FROM foo( (SELECT ARRAY_AGG(data) FROM datatable GROUP BY dataid WHERE dataid = something), 1)
Run Code Online (Sandbox Code Playgroud)
但我想让它处理多组数据,而不将 a 传递dataid给函数。我尝试了多种变体:
SELECT dataid, (foo(ARRAY_AGG(data)),1).*
FROM dataset
WHERE dataid = something -- only testing on 1
GROUP BY dataid
Run Code Online (Sandbox Code Playgroud)
但该函数会为每一列调用一次。