2013-06-10 2 views
6

Here Я задал вопрос о нерабочем запросе.value> = all (select v2 ...) производит разные результаты от значения = (выберите max (v2) ...)

Случайно (с помощью одного ответа) Я нашел, как правильно решить проблему. Проблема в том, что я не понимаю, почему они дают разные результаты.

Таким образом, база данных содержат эту схему:

enter image description here

И Я ищу все модели от PC, Printer и Laptop с ценой высокого. Все эти таблицы могут иметь неповторимый столбец model, поскольку элементы с разными code могут иметь одинаковую модель.

Мое первоначальное решение было:

with model_price(model,price) as (
select model,price 
from PC 

union 

select model,price 
from Laptop 

union 

select model,price 
from Printer 
) 

select model 
from model_price 
where price >= all(select price from model_price) 

Он дал неправильный результат - система возвращается * Wrong number of records (less by 2).

Скорректированный решение, которое работает следующим образом:

with model_price(model,price) as (
select model,price 
from PC 

union 

select model,price 
from Laptop 

union 

select model,price 
from Printer 
) 

select model 
from model_price 
where price = (select max(price) from model_price) 

Итак, почему решение с all производит другой результат?


О SqL двигателя: Now we use Microsoft SQL Server 2012 on the rating stages, and MySQL 5.5.11, PostgreSQL 9.0, and Oracle Database 11g on the learn stage in addition. Так что я не знаю, какой двигатель именно они используют ослов это упражнение.

+1

Любые 'NULL' в данных? 'select 1 where 1> = ALL (select null union select 0)' не возвращает строк. –

+0

Извините, я не знаю данных для второй базы данных (это сделано намеренно для тех, кто делает упражнения не обманывать). Я даже не вижу результата для запросов во второй БД, только рефераты, что не так, например. '* Неверное количество записей (меньше на 2)'. – ovgolovin

ответ

5
create table t (f int null); 

select 1 where 1 >= (select max(f) from t); -- 1 
select 1 where 1 >= all(select f from t); -- 2 

insert into t values (null), (0); 

select 1 where 1 >= (select max(f) from t); -- 3 
select 1 where 1 >= all(select f from t); -- 4 

http://www.sqlfiddle.com/#!6/3d1b1/1

Первый select возвращает ничего, второй select возвращается 1.

MAX возвращает скалярное значение. Если строк нет, MAX возвращает NULL. 1 >= NULL не соответствует действительности в строке 1. С другой стороны, 1 >= all f s является истинным, потому что нет f s вообще, для которого условие не true.

Третий select возвращает 1, четвертый select ничего не возвращает.

MAX, как и все агрегированные функции, игнорирует NULL s. MAX(f) - 0 на линии 3, а 1 >= 0 - это правда. ALL не делает: он оценивает 1 >= NULL AND 1 >= 0 на линии 4, что неверно.

+0

Обратите внимание, что вы можете использовать 'ISNULL' (aka' ISNULL (price, 0) '), если вы хотите использовать' ALL' по другой причине. – Guvante

+0

Спасибо!Вероятно, это упражнение, которое я должен извлечь из этой задачи! Таким образом, 'NULL' не увеличивается до' 0' автоматически при сравнении. – ovgolovin

+0

Правильно, и если возможно, что все значения поля будут отрицательными, обработка 'NULL' как' 0' может даже быть очень неправильной, поэтому, вероятно, хорошо, что база данных не делает это автоматически. Это может иметь смысл даже для полевой «цены», если у вас есть специальные «скидки». – hvd

Смежные вопросы