PostgreSQL - 在结果中获得匹配的数组字段值

时间:2016-08-18 06:48:32

标签: sql postgresql

如果我有查询在Array列中查找值列表,是否有办法将matched值作为结果表中的计算列?

想象一下以下查询:

SELECT name, tags
FROM Books
WHERE Books.tags && ARRAY['APLLE', 'ORANGE']::varchar[]

这就是我打算得到的结果:

| name    | tags              | query    | <- I WANT query COLUMN
|---------|-------------------|----------|
| Cooking | {APPLE, EGGPLANT} | "APPLE"  |
| Frying  | {TOMATO, ORANGE}  | "ORANGE" |
| Boiling | {APPLE}           | "APPLE"  |

3 个答案:

答案 0 :(得分:3)

尝试

CREATE OR REPLACE FUNCTION array_intersect (array1 varchar[], array2 varchar[]) RETURNS varchar[] 
  AS $$ 
     DECLARE 
       out VARCHAR[];
       i varchar;
     BEGIN 
        IF array1 IS NULL OR array2 IS NULL THEN 
           RETURN NULL; 
        END IF; 
        FOR i IN array1 LOOP 
           IF (i = ANY (array2)) THEN 
              out := array_append(out,i); 
           END IF; 
        END LOOP; 
        RETURN out; 
     END; 
$$ LANGUAGE PLPGSQL; 

然后

SELECT name, tags,  array_intersect(tags, ARRAY['APLLE', 'ORANGE']::varchar[])
FROM Books

答案 1 :(得分:3)

SELECT name, tags, fruit AS query
FROM Books
JOIN (VALUES ('APPLE', 'ORANGE')) f(fruit) ON true
-- or JOIN unnest(ARRAY['APPLE', 'ORANGE']::varchar[]) f(fruit) ON true if so desired
JOIN unnest(Books.tags) b(tags) ON b.tags = f.fruit;

如果多个书籍标签与数组值匹配,这将为您提供多本书。如果你想避免使用:

SELECT name, tags, string_agg(fruit, ', ') AS query
...
GROUP BY name, tags;

答案 2 :(得分:3)

select name, b.tags, (
    select string_agg(t,',')
    from
        unnest(b.tags) t(t)
        inner join
        unnest(v.tags) s(t) using (t)
    ) as query
from
    books b
    inner join
    (values (array['APPLE', 'ORANGE']::varchar[])) v(tags) on b.tags && v.tags
;
  name   |       tags       | query  
---------+------------------+--------
 Cooking | {APPLE,EGGPLANT} | APPLE
 Frying  | {TOMATO,ORANGE}  | ORANGE
 Boiling | {APPLE}          | APPLE

数据:

create table books (name text, tags varchar[]);
insert into books (name, tags) values
('Cooking','{APPLE, EGGPLANT}'),
('Frying','{TOMATO, ORANGE}'),
('Boiling','{APPLE}');