SQL |如果存在另一个具有相等(b,c)的元组,则列出所有元组(a,b,c)
我有三个表,其中粗体属性是主键SQL |如果存在另一个具有相等(b,c)的元组,则列出所有元组(a,b,c),sql,postgresql,set,equality,Sql,Postgresql,Set,Equality,我有三个表,其中粗体属性是主键 餐厅(餐厅ID,名称,…) 标识符(餐厅ID,食品ID) 食品(食品ID,名称,…) 使用postgres,我想列出所有与至少一家其他餐厅共享同一套食物的餐厅(餐厅id和名称-每家餐厅1行) 比如说 ID为“1”的餐厅只有相关的食物ID为1和4,如标识符所示 ID为“3”的餐厅只有相关的食物ID为4和1,如标识符所示 ID为“7”的餐厅只有相关食物ID为6,如标识符所示 ID为“9”的餐厅只有相关食物ID为6,如标识符所示 然后输出 任何帮助都将不
- 餐厅(餐厅ID,名称,…)
- 标识符(餐厅ID,食品ID)
- 食品(食品ID,名称,…)
- ID为“1”的餐厅只有相关的食物ID为1和4,如
标识符所示
- ID为“3”的餐厅只有相关的食物ID为4和1,如
标识符所示
- ID为“7”的餐厅只有相关食物ID为6,如
标识符所示
- ID为“9”的餐厅只有相关食物ID为6,如
标识符所示
- 然后输出
谢谢你我理解你的问题,你希望所有餐厅的食物清单与餐厅1相同 如果是这样,那就是关系划分问题。下面是一种使用联接和聚合的方法:
select r.name
from identifier i1
inner join identifier i2 on i2.food_id = i1.food_id
inner join restaurant r on r.restaurant_id = i2.restaurant_id
where i1.restaurant_id = 1
group by r.restaurant_id
having count(*) = (select count(*) from identifier i3 where i3.restaurant_id = 1)
使用聚合函数
string\u agg()
获取每个餐厅的完整食物列表:
with cte as (
select restaurant_ID,
string_agg(food_ID::varchar(10),',' order by food_ID) foods
from identifier
group by restaurant_ID
)
select r.*
from Restaurants r inner join cte c
on c.restaurant_ID = r.restaurant_ID
where exists (select 1 from cte where restaurant_ID <> c.restaurant_ID and foods = c.foods)
请参阅。
这里有一种方法可以获得一套独特的餐厅,它们拥有完全相同的食物。这使用了array_agg()和array_to_string()函数
With cte as
(select T.restaurant_id, array_to_string(array_agg(food_id), ',') as food_list
from
(select *
from Identifier t1
order by restaurant_id, food_id) T
group by T.restaurant_id)
select
concat(r1.name,',',r2.name) as resturant_names,
t1.restaurant_id as restaurant_id1,
r1.name as restaurant_1,
t2.restaurant_id as restaurant_id2,
r2.name as restaurant_2,
t1.food_list as common_food_ids
from cte t1
join cte t2
on t1.restaurant_id < t2.restaurant_id
and t1.food_list = t2.food_list
left join Restaurants r1
on t1.restaurant_id = r1.restaurant_id
left join Restaurants r2
on t2.restaurant_id = r2.restaurant_id;
你的意思是你想在你的例子中列出id为1和3的两家餐馆,而不仅仅是3家。是吗?1.你的示例数据和解释不匹配?2.为什么只列出餐厅
3
而不列出1
?您应该在问题中包含您试图解决此问题的代码。很抱歉,该示例中有错误。我现在已经修好了。如果有另外两家餐厅的食物收集完全相同,但与1号和3号餐厅的食物收集不同,该怎么办?在这种情况下,你的预期结果是什么?嘿,对不起,我意识到我写的那个问题非常糟糕。我想列出所有与至少一家其他餐厅共享同一套食物的餐厅。哇。。。非常感谢你抽出时间帮助一个陌生人。我以后一定会把我的问题弄清楚的!非常感谢您抽出时间回答!
Restaurant_id name
1 name1
3 name3
7 ...
9 ...
select r.name
from identifier i1
inner join identifier i2 on i2.food_id = i1.food_id
inner join restaurant r on r.restaurant_id = i2.restaurant_id
where i1.restaurant_id = 1
group by r.restaurant_id
having count(*) = (select count(*) from identifier i3 where i3.restaurant_id = 1)
with cte as (
select restaurant_ID,
string_agg(food_ID::varchar(10),',' order by food_ID) foods
from identifier
group by restaurant_ID
)
select r.*
from Restaurants r inner join cte c
on c.restaurant_ID = r.restaurant_ID
where exists (select 1 from cte where restaurant_ID <> c.restaurant_ID and foods = c.foods)
with cte as (
select restaurant_ID,
string_agg(food_ID::varchar(10),',' order by food_ID) foods
from identifier
group by restaurant_ID
)
select string_agg(r.name, ',') restaurants
from Restaurants r inner join cte c
on c.restaurant_ID = r.restaurant_ID
group by foods
having count(*) > 1
With cte as
(select T.restaurant_id, array_to_string(array_agg(food_id), ',') as food_list
from
(select *
from Identifier t1
order by restaurant_id, food_id) T
group by T.restaurant_id)
select
concat(r1.name,',',r2.name) as resturant_names,
t1.restaurant_id as restaurant_id1,
r1.name as restaurant_1,
t2.restaurant_id as restaurant_id2,
r2.name as restaurant_2,
t1.food_list as common_food_ids
from cte t1
join cte t2
on t1.restaurant_id < t2.restaurant_id
and t1.food_list = t2.food_list
left join Restaurants r1
on t1.restaurant_id = r1.restaurant_id
left join Restaurants r2
on t2.restaurant_id = r2.restaurant_id;
With cte as
(select T.restaurant_id, array_to_string(array_agg(food_id), ',') as food_list
from
(select *
from Identifier t1
order by restaurant_id, food_id) T
group by T.restaurant_id)
select
--concat(r1.name,',',r2.name) as resturant_names,
t1.restaurant_id as restaurant_id,
r1.name as restaurant--,
--t2.restaurant_id as restaurant_id2,
--r2.name as restaurant_2,
--t1.food_list as common_food_ids
from cte t1
join cte t2
on t1.restaurant_id = t2.restaurant_id
and t1.food_list = t2.food_list
left join Restaurants r1
on t1.restaurant_id = r1.restaurant_id
left join Restaurants r2
on t2.restaurant_id = r2.restaurant_id;