简体   繁体   English

列表列的SQL WHERE子句

[英]SQL WHERE clause for column of lists

How can I specify a WHERE clause, so that it returns a row if there is an intersection between the column's value (list of strings) and another list of strings provided? 我如何指定WHERE子句,以便在列的值(字符串列表)和提供的另一个字符串列表之间存在交集的情况下返回一行? Something like: 就像是:

SELECT id, names
FROM table
WHERE ANY(names) = ANY(('John', 'Alice', 'Bob'))

So if the value names column is, eg ['George', 'Bob'] , the row should be returned. 因此,如果值names列为例如['George', 'Bob'] ,则应返回该行。

You should really use arrays or a table of records for this . 您实际上应该为此使用数组或记录表

You can work around your design by splitting strings into arrays at runtime and using PostgreSQL's array features . 您可以通过在运行时将字符串拆分为数组使用PostgreSQL的数组功能来解决设计问题

SELECT id, names
FROM table
WHERE string_to_array(names, ',') && ARRAY['John', 'Alice', 'Bob'];

If your comma separated values have spaces, etc, you might want regexp_split_to_array instead of string_to_array . 如果逗号分隔的值包含空格等,则可能需要regexp_split_to_array而不是string_to_array

If you really can't change your design (which I would recommand, as mentionned by Craig Ringer) 如果您真的无法更改设计(我建议,正如克雷格·林格(Craig Ringer)所述)

You may use regexp_split_to_array 您可以使用regexp_split_to_array

 SELECT id, names
    from (
    SELECT 
          id,
          names,
          regexp_split_to_table(names, ', ') as splitted_value
    from <yourTable>) t
    where splitted_value in ('John', 'Alice', 'Bob')
    group by id, names;

or more complicated, with your sample 或更复杂的样品

SELECT id, names
    from (
    SELECT 
          id,
          names,
          regexp_split_to_table(replace(replace(names, '[''', ''), ''']', ''), ''', ''') as splitted_value

    from <yourTable>) t
    where splitted_value in ('John', 'Alice', 'Bob')
    group by id, names;

Another ugly way, using some json functions (as your column datas look like json) 使用某些json函数的另一种丑陋方式(因为您的列数据看起来像json)

"Detail" : I'm not a postgresql expert, and less than all in json datas part. “详细信息” :我不是Postgresql专家,并且少于json数据部分中的所有内容。 So there may be much better way to do this. 因此,可能会有更好的方法来执行此操作。

select id, names 
from
 (select 
    id, 
    names,
    replace(cast(json_array_elements(cast(replace(names, '''', '"') as json)) as text), '"', '') as elem
  from <yourTable>) t
where elem in ('George', 'Bob');

You can generate your own function which will mimic MYSQL`s FIND_IN_SET 您可以生成自己的函数来模仿MYSQL的FIND_IN_SET

CREATE OR REPLACE FUNCTION find_in_set(str text, strlist text)
RETURNS int AS $$
SELECT i
   FROM generate_subscripts(string_to_array($2,','),1) g(i)
  WHERE (string_to_array($2, ','))[i] = $1
  UNION ALL
  SELECT 0
  LIMIT 1
$$ LANGUAGE sql STRICT;

http://okbob.blogspot.ro/2009/08/mysql-functions-for-postgresql.html http://okbob.blogspot.ro/2009/08/mysql-functions-for-postgresql.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM