2016-04-08 6 views
0

Так что я имею этот код SQL:SQL левой присоединиться к имея пункт

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 возвращает: не группа по выражению Тхо у меня еще есть группа по в моем коде. Моя цель - получить предметы из камня, цена которых выше средней цены всех камней.

ответ

1

Вы можете сделать это с помощью функции окна:

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; 

Обратите внимание, что условие на внешней соединенной таблице по существу превращает ваше внешнее соединение int o внутреннее соединение. Если вы хотите включить строки, которые не имеют матч в stone_price вам нужно

where price is null 
    or price > avg_price; 

В противном случае вы можете просто изменить left join к «простой» join


Другим вариантом является простой суб -выберите:

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); 
0
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) 

Необходимо использовать функции агрегации для всех столбцов в разделе having. Поэтому, если вы хотите, чтобы камни имели хотя бы один выигрыш выше среднего, вы можете использовать max(). Если все должно быть выше, используйте min().

+0

Это избавило от ошибки, но теперь я не получаю никакого результата, а не с min или max, и я должен получить по крайней мере один. Любая мысль? – user3062657

+0

Я обновил ответ. –

0

Один подход заключается в использовании хранимой процедуры, Вы можете установить переменную так:

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

Затем в ЗЕЬЕСТЕ

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 
+0

Это не подходит для Oracle –

+0

Это кажется хорошей идеей, я никогда не видел и не делал этого только с базовым SQL, но я получаю эту идею. Я работаю в SqlDeveloper, и я получаю ошибку при @ при объявлении переменной: встретил символ «@», ожидая одно из следующего: начало функции pragma procedure подтип тип <идентификатор> <двойное кавычки с разделителями- идентификатор> текущий курсор удалить существует до – user3062657

+0

О, это правда ... это SQL для SQL Server. Но это был бы один подход к Oracle. Объявите переменную, получите среднее значение, а затем используйте это в предложении where. – logixologist