Reputation: 127
I have to find the highest price from three different tables but I do not know how to get the max of P now.
PC(model,speed,ram,hd,price)
Laptop(model,speed,ram,hd,screen,price)
Printer(model,color,type,price)
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);
Could i just add MAX in front? like
SELECT model
FROM MAX((SELECT MAX(price)
FROM PC)
UNION
(SELECT MAX(price)
FROM Laptop)
UNION
(SELECT MAX(price)
FROM Printer));
Upvotes: 1
Views: 1370
Reputation: 5739
You can, if you use MAX in a subquery:
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
This is bigger, but is actually faster than simply selecting the whole tables and ordering, because it gives better chances for optimization by the database engine(It doesn't need to sort all records, just the ones that matter). Testing on Postgresql, it ran at half the time on a very large database.
Upvotes: 1
Reputation: 1270493
If you want the model, use union all
and order by
. You don't specify the database, so here is the ANSI standard solution:
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;
The only part of this that would really differ among databases is the FETCH FIRST 1 ROW ONLY
. This might be limit
, top
, or some other construct.
Upvotes: 3
Reputation: 2320
Note: You haven't specified a vendor, and I'll use Oracle documentations for my answer (however it might be portable).
Do you only need the highest price? Then the subquery will suffice for now, but you use the aggregate function incorrectly:
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
)
However, if you need to have the model also, you'll need a slightly different approach.
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
)
Here, we:
The result is the globally max price and it's related model. If you have multiple rows with the same price, it still returns only one, the last that the order walks through.
The best approach would be to get the ID of the desired row, and have this analytic selection as a subquery. Then fetch the only row that has this ID.
Upvotes: 1
Reputation: 9063
If you want to get only 1 record with highest price you should use TOP 1
. Something like that:
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;
Upvotes: 1
Reputation: 5238
First of all, you should to find max(price)
for each table. In this case, query will calculate all using indices (provided you have one for price).
UPD: Further, you better to normalize tables and extract price (and other common fields) to separate table. That will allow you to use this table for price manipulations and treat your entities without care about their concrete types.
Upvotes: 1