2016-08-18 113 views
0

如果我有一个查询在Array列中查找值列表,有没有办法将matched值作为结果表中的计算列?PostgreSQL - 在结果中获得数组字段的匹配值

想象一下下面的查询:

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" | 
+1

你能用PLSQL或只是标准的SQL? –

+0

@VladCălinBuzea,是的。 – norbertpy

回答

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}'); 
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 
+0

你可以指向文档吗?我似乎没有找到'array_intersect'。 – norbertpy

+1

我更新了我的答案。看来array_intersect不是一个标准功能 –

+0

'创建或替换函数array_intersect(anyarray,anyarray)将anyarray不可变语言sql返回为$$ 从unnest($ 1)select array_agg(t1.v)as t1(v)join unnest $ 2)as t2(v)on(t1.v = t2.v) $$;' – Abelisto

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;