2015-03-06 11 views
0

Мне нужно найти самую высокую цену из трех разных таблиц, но я не знаю, как получить максимальное значение P сейчас.Найти самую высокую цену из трех разных таблиц

PC (модель, скорость, баран, HD, цена)

ноутбука (модель, скорость, баран, HD, экран, цена)

Printer (модель, цвет, тип, цена)

SELECT model 
FROM ((SELECT MAX(price) 
     FROM PC) 
     UNION 
     (SELECT MAX(price) 
     FROM Laptop) 
     UNION 
     (SELECT MAX(price) 
     FROM Printer)) AS P 
WHERE MAX(P); 

Могу ли я просто добавить MAX спереди? как

SELECT model 
FROM MAX((SELECT MAX(price) 
    FROM PC) 
    UNION 
    (SELECT MAX(price) 
    FROM Laptop) 
    UNION 
    (SELECT MAX(price) 
    FROM Printer)); 
+2

Вы попробовали? И вы хотите получить записи с самой высокой ценой из любой таблицы или только с самой высокой ценой? –

+1

Какая СУБД вы используете? Postgres? Oracle? –

+0

См. [«Если вопросы включают« теги »в их названиях?»] (Http://meta.stackexchange.com/questions/19190/should-questions-include-tags-in-their-titles), где консенсус «нет, они не должны»! –

ответ

2

Если вы хотите модель, используйте union all и order by. Вы не указать базу данных, так что здесь является стандартным решением ANSI:

SELECT model, price 
FROM ((SELECT model, price FROM PC) 
     UNION ALL 
     (SELECT model, price FROM Laptop) 
     UNION ALL 
     (SELECT model, price FROM printer) 
    ) p 
ORDER BY price desc 
FETCH FIRST 1 ROW ONLY; 

Единственная часть этого, что бы действительно различаются между базами данных является FETCH FIRST 1 ROW ONLY. Это может быть limit, top или какая-либо другая конструкция.

0

Если вы хотите получить только 1 запись с самой высокой ценой, которую вы должны использовать TOP 1. Нечто подобное:

SELECT TOP 1 model 
FROM ((SELECT MAX(price) 
     FROM PC) 
     UNION 
     (SELECT MAX(price) 
     FROM Laptop) 
     UNION 
     (SELECT MAX(price) 
     FROM Printer)) AS P 
WHERE MAX(P) 
ORDER BY P DESC; 
+1

С этим вы получаете первую цену этих трех, не обязательно самую высокую. –

+0

Можете ли вы действительно иметь агрегатные функции в предложении WHERE? И в чем цель? – jarlh

0

Прежде всего, вы должны найти max(price) для каждой таблицы. В этом случае запрос будет вычислять все с использованием индексов (если у вас есть цена).

UPD: Кроме того, вы можете нормализовать таблицы и извлечь цену (и другие общие поля) для разделения таблицы. Это позволит вам использовать эту таблицу для манипулирования ценами и обращаться с вашими объектами, не заботясь об их конкретных типах.

0

Примечание: вы не указали поставщика, и я буду использовать документацию Oracle для моего ответа (однако он может быть переносимым).

Вам нужна только самая высокая цена? Тогда подзапрос будет достаточно для теперь, но использовать агрегатную функцию неправильно:

SELECT 
    MAX(PRICE) AS HIGHEST_FROM_ALL_TABLES 
FROM 
    (
    SELECT MAX(PRICE) AS PRICE FROM PC 
    UNION 
    SELECT MAX(PRICE) AS PRICE FROM LAPTOP 
    UNION 
    SELECT MAX(PRICE) AS PRICE FROM PRINTER 
) 

Однако, если вам необходимо иметь модель также, вам потребуется несколько иной подход.

SELECT 
    MAX(PRICE) KEEP(DENSE_RANK LAST ORDER BY PRICE) AS HIGHEST_PRICE, 
    MAX(MODEL) KEEP(DENSE_RANK LAST ORDER BY PRICE) AS THE_MODEL 
FROM 
    (
    SELECT PRICE, MODEL FROM PC 
    UNION ALL 
    SELECT PRICE, MODEL FROM LAPTOP 
    UNION ALL 
    SELECT PRICE, MODEL FROM PRINTER 
) 

Здесь мы:

  1. Unite три таблицы, которые, к счастью, имеют один и тот же макет столбца.
  2. Используйте аналитическую функцию LAST без раздела, чтобы получить только одну строку в конце. (mssql перевод: here)

В результате получается глобально максимальная цена и соответствующая модель. Если у вас несколько строк с одинаковой ценой, оно все равно возвращает только одно, последнее, что происходит при прохождении заказа.

Наилучшим подходом было бы получить идентификатор нужной строки и использовать этот аналитический выбор в качестве подзапроса. Затем выберите единственную строку, которая имеет этот идентификатор.

0

Вы можете, если вы используете MAX в подзапросе:

SELECT model FROM (
    (SELECT model, price FROM PC) 
    union 
    (SELECT model, price FROM Laptop) 
    union 
    (SELECT model, price FROM Printer) 
) as AllPrices 
WHERE price = (
    select max(val) from (
     (SELECT max(price) as val FROM PC) 
     union 
     (SELECT max(price) as val FROM Laptop) 
     union 
     (SELECT max(price) as val FROM Printer) 
    ) as MaxPrices 
) 
LIMIT 1 

Это больше, но на самом деле быстрее, чем просто выбирая целые таблицы и порядок, потому что это дает более широкие возможности для оптимизации движка базы данных (Это не нужно сортировать все записи, только те, которые имеют значение). Тестирование на Postgresql, оно выполнялось в половине случаев в очень большой базе данных.

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