繁体   English   中英

具有多个内部联接的 SQL 查询返回错误的值计数

[英]SQL Query with multiple Inner Joins returns wrong Count of Values

我是 sql 的新手,我正在 oracle 中创建的数据库上练习关于阿姆斯特丹和柏林的 airbnb 列表。 我正在尝试加入表 HOSTS (host_id, host_name)、LISTINGS(包括两个城市中的所有列表,其属性为 listings_id、listings_name、Price、host_id...)、Neighborhoods(Neighbourhood_Group、City 和 Neighbourhood)和评论(以 review_id、listings_id 作为外键、reviewer_id、reviewer_name 和 comment)。

现在我想写一个查询,它返回平均价格、最低价格、最高价格、城市(柏林或阿姆斯特丹)、社区(Centrum、Alexanderplatz...)、列表数量和评论数量,所有按不同的社区和 WHERE 语句分组,这将限制返回到那些由总共少于 3 个房源的房东托管的房源。

现在,如果我在没有评论表的情况下运行查询并且只按 amount_listings 对其进行排序,我会得到每个街区“amount_listings”列的正确列表数量。


SELECT avg(l.price) as Mean_Price, 
n.city, 
n.neighbourhood, 
count (l.listings_id) as amount_listings,
min(l.price),
max(l.price)
    FROM listings l
    INNER JOIN neighborhood n
    ON l.neighbourhood = n.neighbourhood

    INNER JOIN hosts h
    ON l.host_id = h.host_id

WHERE h.host_id IN (
    SELECT host_id
    FROM listings
    GROUP BY host_id
    HAVING count(host_id) < 3
)
GROUP BY n.neighbourhood, n.city
ORDER BY amount_listings DESC;

在此处输入图片说明

但是如果我在查询中包含评论数量,结果是不正确的。 评论数量和列表数量列显示错误数量(太多)。

SELECT avg(l.price) as Mean_Price, count(l.listings_id) as amount_listings, 
       min(l.price), max(l.price), n.city, n.neighbourhood, count(r.review_id) as amount_reviews
FROM listings l
INNER JOIN neighborhood n
ON l.neighbourhood = n.neighbourhood

INNER JOIN hosts h
ON l.host_id = h.host_id

INNER JOIN reviews r
ON l.listings_id= r.listings_id
WHERE h.host_id IN (
    SELECT host_id
    FROM listings
    GROUP BY host_id
    HAVING count(host_id) < 3
)

GROUP BY n.neighbourhood, n.city
ORDER BY amount_listings DESC, amount_reviews DESC;

在此处输入图片说明

我不知道为什么amount_listings 和amount_reviews 返回这样错误的结果。

原因是,由于您要添加一个多于 0 行的新表,因此记录会被计算多次,具体取决于评论的数量。 由于您只对评论数量感兴趣,让我们用一个很好的老技巧来代替它:

SELECT avg(l.price) as Mean_Price, count(l.listings_id) as amount_listings, 
       min(l.price), max(l.price), n.city, n.neighbourhood, r.review_count as amount_reviews
FROM listings l
INNER JOIN neighborhood n
ON l.neighbourhood = n.neighbourhood

INNER JOIN hosts h
ON l.host_id = h.host_id

INNER JOIN (select reviews.listings_id as listings_id, count(*) as review_count from reviews where reviews.listings_id = l.listings_id) r
ON l.listings_id= r.listings_id
WHERE h.host_id IN (
    SELECT host_id
    FROM listings
    GROUP BY host_id
    HAVING count(host_id) < 3
)

GROUP BY n.neighbourhood, n.city
ORDER BY amount_listings DESC, amount_reviews DESC;

加入前聚合。 您希望将评论计数加入每个列表,然后将汇总的列表信息加入社区。

select
  lr.mean_price,
  n.city,
  n.neighbourhood,
  lr.amount_listings,
  lr.min_price,
  lr.max_price,
  lr.amount_reviews
from neighborhood n
join
(
  select
    l.neighbourhood,
    min(l.price) as min_price,
    max(l.price) as max_price,
    avg(l.price) as mean_price,
    count(*) as amount_listings,
    coalesce(sum(r.reviews_for_listing), 0) as amount_reviews
  from listings l
  left join
  (
    select
      listings_id,
      count(*) as reviews_for_listing
    from reviews
    group by listings_id
  ) r on r.listings_id = l.listings_id
  where l.host_id in
  (
    select host_id
    from listings
    group by host_id
    having count(*) < 3
  )
  group by l.neighbourhood
) lr on lr.neighbourhood = n.neighbourhood
order by n.city, n.neighbourhood;

暂无
暂无

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

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