2012-07-06 88 views
0
select model from (
    select price, model from pc where price = (select max(price) from pc) 
    union 
    select price, model from laptop where price = (select max(price) from laptop) 
    union 
    select price, model from printer where price = (select max(price) from printer) 
) t1 where price = (select max(price) from (
    select price, model from pc where price = (select max(price) from pc) 
    union 
    select price, model from laptop where price = (select max(price) from laptop) 
    union 
    select price, model from printer where price = (select max(price) from printer) 
) t2) 

我對SQL很陌生,所以我的問題很簡單,但我想解決一點。我是對的,這個查詢不能被簡化成這樣的東西?SQL查詢簡化

select model from (
    select price, model from pc where price = (select max(price) from pc) 
    union 
    select price, model from laptop where price = (select max(price) from laptop) 
    union 
    select price, model from printer where price = (select max(price) from printer) 
) t1 where price = (select max(price) from t1) 

如果這是不可能的,是什麼讓我們運行兩個相同的子查詢壞事?

+0

只有看的查詢,很難理解表結構,你想要實現什麼。 – 2012-07-06 13:40:48

+1

您正在使用哪種RDBMS? – MatBailie 2012-07-06 13:46:29

+0

我們有pc,筆記本電腦和打印機表格,每列有兩列:型號和價格。目標是從所有表格中找出最昂貴的模型。 MySQL的。 – ivkremer 2012-07-06 13:46:50

回答

1

我還是說要去一張桌子,這是最好的實踐設計。 (不是重複相同的表不必要的。)

CREATE TABLE unified_table (
    product_type, 
    price, 
    model 
) 

這樣做使此查詢...

SELECT 
    * 
FROM 
    unified_table 
WHERE 
    price = (SELECT MAX(price) FROM unified_table) 

但是,如果你不能或不會,相信優化器來處理與聯盟的後果...

SELECT 
    * 
FROM 
(
    SELECT * FROM pc 
    UNION ALL 
    SELECT * FROM laptop 
    UNION ALL 
    SELECT * FROM printer 
) t1 
WHERE 
    price = (SELECT MAX(price) FROM (SELECT price FROM pc 
            UNION ALL 
            SELECT price FROM laptop 
            UNION ALL 
            SELECT price FROM printer 
           ) t2 
     ) 

優化程序將瞭解如何優化,以消除多餘的搜索。


編輯:

作爲妥協,你可以做一個統一的視圖,查詢...

CREATE VIEW unified_table AS 
    SELECT 'pc'  AS type, * FROM pc 
    UNION ALL 
    SELECT 'laptop' AS type, * FROM laptop 
    UNION ALL 
    SELECT 'printer' AS type, * FROM printer 
+0

好的,所以我想這不是因爲優化器而在最後一個代碼示例中重複查詢的問題? – ivkremer 2012-07-06 14:03:51

+0

@Kremchik - 將單獨創建和處理'T1'和'T2'。但是你不需要在'T2'中執行三個MAX()es,優化器已經知道如何執行三個UNIONed表的MAX()。而且你不需要在'T1'中預先過濾每個表格,優化器只需要從'T2'的MAX()結果搜索每個表格一次。 – MatBailie 2012-07-06 14:07:48

0

嘗試這樣:

select model, price 
from (
    select price, model from pc order by price desc limit 1 
    union 
    select price, model from laptop order by price desc limit 1 
    union 
    select price, model from printer order by price desc limit 1 
) t1 
order by price desc 
limit 1 

不過我建議你檢查你的數據庫結構,這似乎是你創建了多個表基於類型相同的東西(的項目)。您可以將所有這些保留在一個表中,僅通過類型列的內容進行區分。

無極限:

select t1.model, t1.price 
from 
(select max(price) p 
from 
    select max(price) p from pc 
    union 
    select max(price) p from laptop 
    union 
    select max(price) p from printer 
) max_price 
JOIN (
    select price, model from pc 
    union 
    select price, model from laptop 
    union 
    select price, model from printer 
) t1 ON price >= max_price.p 
+0

謝謝!但是我不認爲我可以使用'limit 1'語句,因爲可以存在兩個或更多個價格相同的最高價格的模型。 – ivkremer 2012-07-06 13:50:00

+0

限制爲MySql ... – 2012-07-06 13:51:00

+0

@Kremchik:這真的很重要嗎? – Matzi 2012-07-06 13:56:51

0
select * from (
    select price, model from pc where price = (select max(price) from pc) 
    union 
    select price, model from laptop where price = (select max(price) from laptop) 
    union 
    select price, model from printer where price = (select max(price) from printer) 
) order by Price desc limit 1 

既然你有3個值進行比較,從不同的表,沒有關係,你必須做一個聯盟,然後比較它們

這是一種方法,你不需要再次計算價格。

+0

對於sql server ... – 2012-07-06 13:50:33

+0

我們不能使用'limit',因爲可以有兩個或多個價格相同的最高價格的模型。但無論如何,我的問題是:我們可以命名查詢結果,並從中選擇? – ivkremer 2012-07-06 13:58:02