Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 基于逻辑AND而不是逻辑OR查找关联_Sql_Postgresql_Relational Division - Fatal编程技术网

Sql 基于逻辑AND而不是逻辑OR查找关联

Sql 基于逻辑AND而不是逻辑OR查找关联,sql,postgresql,relational-division,Sql,Postgresql,Relational Division,在我的数据模型中,照片可以有许多与之关联的标记 所以我有我的照片表和两张照片 id | file_name ----+---------------------- 1 | DSCN0317.jpg 2 | DSCN0291.jpg 我有两个标签的标签表 id | name ----+---------------- 5 | Vacation 6 | Work 我有一个映射表,把两个连接在一起 photo_id | tag_id ----------+---

在我的数据模型中,照片可以有许多与之关联的标记

所以我有我的照片表和两张照片

 id | file_name
----+----------------------
  1 | DSCN0317.jpg
  2 | DSCN0291.jpg
我有两个标签的标签表

 id |      name
----+----------------
  5 | Vacation
  6 | Work
我有一个映射表,把两个连接在一起

   photo_id | tag_id
----------+--------
        1 |      5
        2 |      5
        2 |      6
所以在这个例子中,照片1有一个标签5,照片2有多个标签5,6

在我的应用程序中,我需要找到所有带有特定标签列表的照片。更重要的是,如果可能的话,我需要在一个查询中完成

为什么它需要是一个单一查询的原因超出了这个问题的范围,并且与我的应用程序的具体实现有关

例如,我想查找同时具有标记5和6的所有照片

SELECT DISTINCT "photos".*
FROM "photos"
INNER JOIN "photo_tags"
  ON "photo_tags"."photo_id" = "photos"."id"
WHERE "photo_tags"."tag_id" IN (5, 6)
;
但是这个查询是不正确的,因为它返回所有带有标签6或7的照片。我正在寻找有6和7的照片

有什么方法可以转换上面的查询来实现这一点吗


谢谢

在标记id上使用聚合和条件不同计数尝试此操作:

select p.*
from photos p
join (
    select 
        photo_id
    from tags
    where 
        tag_id in (5, 6)
    group by 
        photo_id
    having 
        count(distinct tag_id) = 2
) t on p.id = t.photo_id;
或相关查询:

select p.*
from photos p
where exists (
    select
        1
    from tags t
    where
        t.tag_id in (5, 6)
        and t.photo_id = p.id
    group by 
        id
    having 
        count(distinct tag_id) = 2
);

使用标记id上的聚合和条件不同计数尝试此操作:

select p.*
from photos p
join (
    select 
        photo_id
    from tags
    where 
        tag_id in (5, 6)
    group by 
        photo_id
    having 
        count(distinct tag_id) = 2
) t on p.id = t.photo_id;
或相关查询:

select p.*
from photos p
where exists (
    select
        1
    from tags t
    where
        t.tag_id in (5, 6)
        and t.photo_id = p.id
    group by 
        id
    having 
        count(distinct tag_id) = 2
);
您可以使用EXISTS查找ID为5和ID为6的照片:

SELECT "photos".*
FROM "photos"
WHERE EXISTS (
    SELECT "photo_tags"."tag_id" 
    FROM "photo_tags" 
    WHERE "photo_tags"."photo_id" = "photos"."id" 
        AND "photo_tags"."tag_id" = 5)
AND EXISTS (
    SELECT "photo_tags"."tag_id" 
    FROM "photo_tags" 
    WHERE "photo_tags"."photo_id" = "photos"."id" 
        AND "photo_tags"."tag_id" = 6)
您可以使用EXISTS查找ID为5和ID为6的照片:

SELECT "photos".*
FROM "photos"
WHERE EXISTS (
    SELECT "photo_tags"."tag_id" 
    FROM "photo_tags" 
    WHERE "photo_tags"."photo_id" = "photos"."id" 
        AND "photo_tags"."tag_id" = 5)
AND EXISTS (
    SELECT "photo_tags"."tag_id" 
    FROM "photo_tags" 
    WHERE "photo_tags"."photo_id" = "photos"."id" 
        AND "photo_tags"."tag_id" = 6)

在加入之前将标记聚合到数组中。然后检查数组是否包含所需的标记:

select distinct photos.*
from
    photos
    inner join (
        select photo_id as id, array_agg(tag_id) as tags
        from photo_tags
        group by photo_id
    ) photo_tags using(id)
where array[5, 6] <@ tags

在加入之前将标记聚合到数组中。然后检查数组是否包含所需的标记:

select distinct photos.*
from
    photos
    inner join (
        select photo_id as id, array_agg(tag_id) as tags
        from photo_tags
        group by photo_id
    ) photo_tags using(id)
where array[5, 6] <@ tags

谢谢虽然这只是返回p.id,因为这是它的分组依据,所以我仍然需要另一个查询来获取完整的照片records@user2490003-用优化更新了我的答案。若在标签表中的photo_id和tag_id列上有适当的索引,那个么速度应该足够快。请核对一下,谢谢。虽然这只是返回p.id,因为这是它的分组依据,所以我仍然需要另一个查询来获取完整的照片records@user2490003-用优化更新了我的答案。若在标签表中的photo_id和tag_id列上有适当的索引,那个么速度应该足够快。请核对一下,谢谢。你知道这对大型照片表(如100k或更大的记录)的效率有多高吗?我最多只能查询2-3个标记,但我想知道多次运行EXISTS子类是否会对较大的照片表产生影响。@user2490003性能取决于许多因素。如果您在photo_id和tag_id列上有正确的索引,那么性能应该是合理的,但是这取决于实际数据、您的查询、数据的细节、所需的响应时间和许多其他因素。我建议您在数据上测试性能,看看您是否可以接受。谢谢。你知道这对大型照片表(如100k或更大的记录)的效率有多高吗?我最多只能查询2-3个标记,但我想知道多次运行EXISTS子类是否会对较大的照片表产生影响。@user2490003性能取决于许多因素。如果您在photo_id和tag_id列上有正确的索引,那么性能应该是合理的,但是这取决于实际数据、您的查询、数据的细节、所需的响应时间和许多其他因素。我建议你在数据上测试性能,看看你是否可以接受。我甚至不知道你可以这么做!谢谢,将您的标记为已接受,因为我尝试对此处提供的每个查询运行解释和\计时,这是最快的。其他人免责声明:我只在<100行的情况下尝试了这个查询,而这个查询距离GurV的第一个查询不到10毫秒,我甚至不知道你可以这么做!谢谢,将您的标记为已接受,因为我尝试对此处提供的每个查询运行解释和\计时,这是最快的。其他人免责声明:我只在<100行的情况下尝试了这个查询,而这个查询距离GurV的第一个查询不到10毫秒