2015-04-22 74 views
3

我想寫一個SQL查詢來解決一個問題在www.sql-ex.ru(問28),我得到了正確的結果,但我得到了這個錯誤「您的查詢在第三次檢查數據庫時失敗。」SQL-EX.ru查詢問題集#28

SQL查詢問題:

爲兩位十進制數內,定義每平方米塗料的平均數量。

SQL注:

數據庫結構由3個表:

UTQ(Q_ID INT,Q_NAME VARCHAR(35)),UTV(V_ID INT,V_NAME VARCHAR(35) ,V_COLOR char(1)),

utB(B_Q_ID int,B_V_ID int,B_VOL tinyint,B_DATETIME datetime)。 表格utQ包含方形標識符,方形名稱。請注意,未塗漆的正方形是黑色的。

utV包括氣球標識符,氣球名稱和油漆顏色。 表格utB顯示了繪畫廣場上的塗料氣球信息,包括方形標識符,氣球標識符,繪畫數量和繪畫時間。

  • 應當注意的是,球囊可以從三種顏色之一:紅色(V_COLOR = 'R'),綠色(V_COLOR = 'G')或藍色(V_COLOR = 'B');
  • 任何氣球原本已滿,體積爲255;根據RGB規則定義正方形顏色,即R = 0,G = 0,B = 0是黑色,而R = 255,G = 255,B = 255是白色;
  • 表utB中的任何記錄通過B_VOL降低氣球中的塗料量,並將正方形中的塗料量增加相同的值;
  • B_VOL必須大於0且小於或等於255;
  • 一個正方形中相同顏色的塗料量不得超過255;
  • 氣球中的油漆量不得少於0;
  • 繪畫時間(B_DATETIME)在一秒內給出,即它不包含毫秒。

方案

Scheme

我的代碼

WITH x AS (SELECT b_q_id, b_v_id, ball.v_color, b_vol as vol FROM utb 
JOIN utv ball 
ON utb.b_v_id = ball.v_id) 
, y AS (
SELECT b_q_id, v_color, totalcolor = CASE WHEN SUM(vol) > 255 THEN 255 
ELSE SUM(vol) END FROM x 
GROUP BY b_q_id, v_color), 
z AS(
SELECT b_v_id, totalbcolor = 
CASE WHEN SUM(b_vol) > 255 THEN 255 
ELSE SUM(b_vol) 
END 
FROM utb 
GROUP BY b_v_id) 
, a AS 
(SELECT b_q_id, SUM(totalcolor) totalacolor FROM y GROUP BY b_q_id) 
, b AS 
(SELECT b_q_id,b_v_id, totalacolor FROM a, z) 
, c AS 
(SELECT DISTINCT b.b_q_id, totalacolor FROM b 
INNER JOIN utb 
ON (b.b_q_id = utb.b_q_id AND b.b_v_id = utb.b_v_id)) 

SELECT 
CAST(CAST(SUM(totalacolor) AS NUMERIC(8,2)) 
/(SELECT COUNT(*) FROM utq)AS NUMERIC(8,2)) 
FROM c 

正確答案

386。25

評論 我的代碼可能過長。但是,這樣做的方式可能更短。但是,我仍然不明白我錯在哪裏。請幫忙。

回答

5

在這裏你的代碼)

SELECT CONVERT(NUMERIC(15,2),SUM(COALESCE(UB.B_VOL,0))/CONVERT(FLOAT,COUNT(DISTINCT UQ.Q_ID))) 
FROM utQ AS UQ 
     LEFT JOIN utB AS UB ON UQ.Q_ID = UB.B_Q_ID 
     LEFT JOIN utV AS UV ON UB.B_V_ID = UV.V_ID 

測試下方

enter image description here

+2

有沒有必要LEFT JOIN utV表。 – Serge

+0

你應該在發表評論前測試你的假設 – Vasily

+0

@Vasily - 你的代碼有效,但你能解釋爲什麼你需要coalesce命令嗎?沒有它,我會得到「你的查詢失敗,第三次檢查數據庫」,這是我自己的。我不明白我的問題是什麼,爲什麼我需要使用合併。 –

0
如果你想要去旁邊的幫助主題,你可以使用此查詢

SELECT cast(SUM(case when UB.B_VOL IS NULL then 0 else UB.B_VOL end) /cast(COUNT(DISTINCT UQ.Q_ID) as float) as decimal(8,2))FROM utQ AS UQ 
    LEFT JOIN utB AS UB ON UQ.Q_ID = UB.B_Q_ID 
0

這裏是另一個解決方案,使用CASE WHEN ... THEN ... ELSE ... END

SELECT CONVERT(NUMERIC(15,2), 
(
SELECT SUM(total_paint) * 1.0/COUNT(Q_ID) AS avg_paint 
FROM 
(
SELECT DISTINCT utQ.Q_ID, 
CASE 
WHEN SUM(B_VOL) IS NULL 
THEN 0 
ELSE SUM(B_VOL) 
END 
AS total_paint 
FROM utQ 
LEFT JOIN utB ON utB.B_Q_ID = utQ.Q_ID 
GROUP BY utQ.Q_ID 
) AS tmp 
) 
)