2017-04-09 41 views
1

我希望能夠深入瞭解mySQL如何處理這個問題。 所以我想獲得某一列中元素的中位數。看到問題here。我一直在試圖獲取變量@ct中的總行數,並得出一個表格,其中所有行都按照所討論的列的值進行編號和排序。 然後我簡單地查詢其行滿足條件的列的平均值,並且標準取決於@ct是奇數還是偶數。以下是該工作代碼。mySQL中CASE函數的怪異工作

SET @ct := (select count(*) from STATION); %This stores the number of rows 
SET @rowNum :=0; %This will be used to save row number for each row. 


SELECT AVG(q.LAT_N) 

FROM (SELECT LAT_N,(@rowNum:[email protected]+1) n FROM STATION ORDER BY LAT_N) AS q 

WHERE q.n = (CASE @ct%2 WHEN 1 THEN (@ct+1)/2 ELSE @ct/2 OR (@ct+1)/2 END) 

奇怪的是,當在最後一行,而不是使用或排序對兩個值我這樣做,

WHERE q.n = (CASE @ct%2 WHEN 1 THEN (@ct+1)/2 ELSE (@ct/2,(@ct+1)/2) END) 

OR

WHERE q.n IN (CASE @ct%2 WHEN 1 THEN (@ct+1)/2 ELSE (@ct/2,(@ct+1)/2) END) 

我不斷收到語法錯誤Operand should contain 1 column(s) 任何想法是怎麼回事?我是否缺少一些基本的語法規則? 我也嘗試過與IF函數相同的功能。

+1

我不認爲_(@ ct/2,(@ ct + 1)/ 2)_是一個有效的表達式,因爲逗號。它將評估爲兩列,並且您正在針對一列進行測試 –

+0

但我們不在'IN'子句中這樣做嗎? –

+0

'IN'只針對多行而不是多列進行測試。您可以將其視爲行向量與列向量。 – THN

回答

1

您的方法存在多個問題。

由於@ct/2 OR (@ct+1)/2將始終返回1TRUE),所以您的第一個查詢將不能用於偶數。所以你會永遠得到最小的價值。

您的第二個WHERE條件不起作用,因爲CASE表達式不能返回多個列。你可以做的是使用BETWEEN條件:

WHERE q.n BETWEEN (CASE @ct%2 WHEN 1 THEN (@ct+1)/2 ELSE @ct/2 END) 
       AND (CASE @ct%2 WHEN 1 THEN (@ct+1)/2 ELSE (@ct+1)/2 END) 

或者

WHERE 
    CASE WHEN @ct%2 
     THEN q.n = (@ct+1)/2 
     ELSE q.n BETWEEN @ct/2 AND (@ct+1)/2 
    END 

然而(@ct+1)/2是錯誤的,甚至數和應@ct/2+1

但是你甚至不需要CASE表達式。你也可以使用

WHERE q.n BETWEEN @ct/2 
       AND @ct/2+1 
0

這不是你的問題的答案。但我認爲這是解決您的問題。

SET @ct := (select count(*) from STATION); 
SET @rowNum :=0; 
SET @start := floor((@ct+1)/2); 
SET @end := ceil((@ct+1)/2); 

SELECT AVG(q.LAT_N) 

FROM (SELECT LAT_N,(@rowNum:[email protected]+1) n FROM STATION ORDER BY LAT_N) AS q 

WHERE q.n in(@start,@end); 

請嘗試一下。

+0

謝謝,但我已發佈的代碼實際上工作。我只是想知道爲什麼它不能像我發佈的那樣使用其他方式。 –