简体   繁体   中英

SQL Left join with having clause

So I am having this sql code:

select stone_number,stone_size,stone_shape,stone_weight 
from stone
left Join stone_price stp on stp.id_stone = stone.id_stone
group by stone_number,stone_size,stone_shape,stone_weight 
having  avg(stp.price) < stp.price;

Sqldeveloper returns: not a group by expression tho I still have group by in my code. My goal is to get stone items which price is higher then average price of all stones.

You can do that with a window function:

select *
from (
  select stone_number,stone_size,stone_shape,stone_weight, 
         stp.price, 
         avg(stp.price) over () as avg_price
  from stone
    left Join stone_price stp on stp.id_stone = stone.id_stone
)  
where price > avg_price;

Note that the condition on the outer joined table essentially turns your outer join into an inner join. If you also want to include rows that did not have a match in stone_price you need

where price is null
   or price > avg_price;

Otherwise you can just change the left join to a "plain" join


Another option is a simple sub-select:

select stone_number,stone_size,stone_shape,stone_weight, 
from stone
  left Join stone_price stp on stp.id_stone = stone.id_stone
where stp.price > (select avg(price) from stone_price);
select stone_number, stone_size, stone_shape, stone_weight 
from stone
left Join stone_price stp on stp.id_stone = stone.id_stone
group by stone_number, stone_size, stone_shape, stone_weight 
having (select avg(price) from stone_price) < max(stp.price)

You need to use aggregation functions on all columns in the having clause. So if you want to get stones having at least one prize higher than average you can use max() . If all need to be higher use min() .

One approach is to use a stored procedure, You could set a variable like this:

DECLARE @average_price INT
SET @average_price = (SELECT Avg(stone_price) from stone

Then in your SELECT statement

select stone_number,stone_size,stone_shape,stone_weight 
from stone
left Join stone_price stp on stp.id_stone = stone.id_stone
WHERE stone_price > @average_price

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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