2014-10-05 40 views
0

「Smart for Smarties」的SQL書籍顯示計算日期的第一中位數的示例代碼。SQL的日期首位中位數

我把這個例子放在這裏。 http://sqlfiddle.com/#!3/c69520/1

---duplicate to ensure even number of rows 

CREATE VIEW Temp1 
AS SELECT weight FROM Parts 
UNION ALL 
SELECT weight FROM Parts; 

---below this part is what I didn't understand how it works 

CREATE VIEW Temp2 
AS SELECT weight 
FROM Temp1 
WHERE 
(SELECT COUNT(*) FROM Parts) 
<= (SELECT COUNT(*) 
FROM Temp1 AS T1 
WHERE T1.weight >= Temp1.weight) 
AND (SELECT COUNT(*) FROM Parts) 
<= (SELECT COUNT(*) 
FROM Temp1 AS T2 
WHERE T2.weight <= Temp1.weight); 

SELECT AVG(DISTINCT weight) AS median 
FROM Temp2; 

結果是正確的,雖然這個解決方案在時間和存儲方面都很昂貴。

真的很想知道這部分是如何工作的?

我試着看到內部SQL語句的結果。

(SELECT COUNT(*) 
FROM Temp1 AS T1 
WHERE T1.weight >= Temp1.weight) 

,並得到了消息

多部分標識符「Temp1.weight」無法綁定。

如何理解這個SQL?

+0

這被稱爲「相關的子查詢」(你可以看看)。還有其他計算中位數的方法。 – 2014-10-05 12:16:04

回答

0
CREATE VIEW Temp2 
AS SELECT weight 
FROM Temp1 
WHERE 
    (SELECT COUNT(*) FROM Parts) <= (SELECT COUNT(*) 
             FROM Temp1 AS T1 
             WHERE T1.weight >= Temp1.weight 
            ) 
AND 
    (SELECT COUNT(*) FROM Parts) <= (SELECT COUNT(*) 
            FROM Temp1 AS T2 
            WHERE T2.weight <= Temp1.weight 
           ); 

我想你的意思是在上面的代碼。我做了重新格式化,使其更清晰一些(至少對我而言)。 在子查詢中,將名稱Temp1重寫爲T1。當你說t1.weight時,你在子查詢的權重列中引用子查詢中的含義。但是Temp1.weight將是父查詢Temp1表。 這意味着Temp1表中的每一行都會執行一個新的查詢,查看Temp1的所有行並檢查當前行的值。 所以10行將會像200行一樣,那麼當然有了正確的索引等等,實際的rowcount不需要那麼糟糕。

原因你

多部分標識符「Temp1.weight」無法綁定。

是因爲你試圖運行沒有外部查詢的內部查詢,因此服務器不知道你是什麼意思的Temp1。它只知道T1。