Postgres仅选择符合给定集合的项目

时间:2016-05-11 10:32:08

标签: sql postgresql relational-division

我有一张表:

ref_id  value
-------------
 1     test1 
 2     test1
 1     test2
 1     test3

现在我想只选择那些ref_id,如果值属于ref_id,则匹配给定集合的所有值。例如,如果给定的集合看起来像('test1','test2'),结果应该是:

ref_id  
-------
   1

如果集合为('test1'),结果应为:

ref_id
------
  1
  2

3 个答案:

答案 0 :(得分:1)

您可以使用数组:

with t(ref_id,value) as (values
  (1,'test1'),(2,'test1'),(1,'test2'),(1,'test3'))
select ref_id, value from
  (select ref_id, array_agg(distinct value) as value from t group by ref_id) as s
where
  value @> array['test1']
  --value @> array['test1','test2']

或者,更简单:

select ref_id from t
group by ref_id
having array_agg(value) @> array['test1']

详细了解@> operatorarray_agg function

答案 1 :(得分:0)

您可以使用group byhaving执行此操作。你没有指定"设置"看起来像,但这是一个例子:

select ref_id
from t
where value in ('test1', 'test2')
group by ref_id
having count(*) = 2; <-- size of set

答案 2 :(得分:0)

我建议我们的表名为 ref ,并且匹配设置在 matchset 表中。

如果对(ref_id:value)在 ref 表中是唯一的,请尝试以下操作:

with r as(
select distinct ref_id, value
from ref
)
select ref_id
from r
join matchset s
on s.value = r.value
group by ref_id
having count(*)=(select count(*) from matchset)

如果同一对(ref_id:value)可能不止一次出现,我们需要过滤掉重复项

    public static boolean compress(final InputStream pSourceStream, final ZipFile pTarget, final ZipEntry pContainer,
        final String pFileName) {
    if (pSourceStream != null && pTarget != null && pFileName != null && !pFileName.isEmpty()) {
        try {
            final ZipOutputStream output = new ZipOutputStream(new FileOutputStream(new File(pTarget.getName())));
            final ZipEntry target = (pContainer != null) ? new ZipEntry(pContainer.getName() + pFileName)
                    : new ZipEntry(pFileName);
            output.putNextEntry(target);

            final byte[] buffer = new byte[BUFFER_SIZE];
            int readBytes;

            while ((readBytes = pSourceStream.read(buffer)) != -1) {
                output.write(buffer, 0, readBytes);
            }
            pSourceStream.close();
            output.flush();
            output.close();
            return true;
        } catch (final IOException ignore) {
            // took care of target
            // ios will return false
        }

    }
    return false;
}