查找包含所需信息的条目

find entry with needed information

我想提出一个 sql 与除法相关的查询, 我有这样的关系模式:

property(PNO, price, fid); //PNO is the primary key, fid is the feature id, price is the price of the house
buyer(PEID, max_price, fid);//PEID is the primary key, fid is the feature id, max_price is the max price a buyer can pay for a house
feature(FID, content);

一个属性可以有很多功能。一位买家可能需要多项功能。

我想建立的关系是这样的:对于每个买家,列出所有满足买家要求的属性(功能和价格)。 我尝试了很多不同的方法,但仍然无法得到想要的输出。

样本数据就像

//buyers require 0 - many features, and price is the maximum price they can pay for a house, not for a single feature
buyer(0, 10k, 1)
buyer(0, 10k, 2)       //buyer 0 can pay 10k, and requires feature 1 and 2
buyer(1, 15k, 3)
buyer(1, 15k, 4)       //buyer 1 can pay 15k, and requires feature 3 and 4
buyer(2, 150k, null)   //buyer 2 can pay 150k, and no specific requirement
buyer(3, 20k, null)    //buyer 3 can pay 20k, and no specific requirement

//property has 0 - many features, and price is the selling price of the house, not for a single feature
property(5, 5k, 1)
property(5, 5k, 2)     //property 5 is 5k, and has feature 1 and 2
property(6, 6k, 1)
property(6, 6k, 4)     //property 6 is 6k, and has feature 1 and 4
property(7, 6k, 1)
property(7, 6k, 2)
property(7, 6k, 3)
property(7, 6k, 4)     //property 7 is 6k, and has feature 1,2,3,4
property(8, 100k, 3)
property(8, 100k, 4)   //property 8 is 100k, and has feature 3,4

feature(1, '2000 square feet')
feature(2, 'two story')
feature(2, 'one story')
feature(4, 'two bathrooms')

示例输出类似于

buyer     property
-----      --------
0             5        //buyer 0 can afford property 5 with required features
0             7        //buyer 0 can afford property 7 with required features
1             7        //buyer 1 can afford property 7 with required features
2             5        //buyer 2 can afford property 5 
2             6        //buyer 2 can afford property 6 
2             7        //buyer 2 can afford property 7 
2             8        //buyer 2 can afford property 8 
3             5        //buyer 3 can afford property 5 
3             6        //buyer 3 can afford property 6
3             7        //buyer 3 can afford property 7

你可以做一个 join:

select b.*, p.*
from buyer b left join
     property p
     on p.price <= b.max_price;

如果你想把这一切都放在一行中,你可以使用聚合:

select b.PEID, b.max_price,
       listagg(pno, ',') within group (order by pno) as pnos
from buyer b left join
     property p
     on p.price <= b.max_price
group by PEID, max_price

我认为您需要通过按 peidprice 列分组进行聚合,同时连接具有 buyerproperty 表的子查询,其连接条件由属性串联组成,例如作为

SELECT b.peid AS buyer, p.pno AS property
  FROM ( SELECT LISTAGG(fid,',') WITHIN GROUP (ORDER BY fid) AS features, pno 
           FROM property
          GROUP BY pno ) p
  JOIN ( SELECT LISTAGG(fid,',') WITHIN GROUP (ORDER BY fid) AS features, peid 
           FROM buyer
          GROUP BY peid ) b
    ON b.features = p.features;

 BUYER  PROPERTY 
 0      5     
 1      6     

Demo

你说你展示的不是真实的表,而是底层表的查询结果。这很好,否则您的数据库将无法规范化,因此容易出错。

我在下面的回答中假设一个正确规范化的数据库:

  • 特征(feature_id,描述)
  • 买家(buyer_id,金钱,...)
  • buyer_feature (buyer_id, feature_id)
  • 属性(property_id,金钱,...)
  • property_feature (property_id, feature_id)

我们 select 来自价格匹配的买家和物业。然后我们看看是否为找到的 buyer/property 对找到缺失的特征。

select
  b.buyer_id, p.property_id,
  case when exists
    (
      select feature_id from buyer_feature bf where bf.buyer_id = b.buyer_id
      minus
      select feature_id from property_feature pf where pf.property_id = p.property_id
    )
    then 'feature(s) missing'
    else 'all feature requirements met'
  end as feature_status
from buyer b
join property p on p.money <= b.money
order by b.buyer_id, p.property_id;