SQL-EX.ru查询问题集#28

SQL-EX.ru查询问题集#28,sql,tsql,Sql,Tsql,我试图在www.SQL-ex.ru(问题28)上编写一个SQL查询来解决一个问题,我得到了正确的结果,但是我得到了这个错误“您的查询在第三个检查数据库上失败了。” 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 tin

我试图在www.SQL-ex.ru(问题28)上编写一个SQL查询来解决一个问题,我得到了正确的结果,但是我得到了这个错误“您的查询在第三个检查数据库上失败了。”

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)在一秒钟内给定,即不包含毫秒
方案

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

我的代码

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

评论 我的代码可能太长了。但是,可能还有一种更短的方法。但是,我仍然不明白我错在哪里。请帮助。

这是您的代码)

下面的测试


如果您想查看帮助主题,可以使用以下查询:

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

下面是另一个解决方案,当。。。然后。。。其他的结束:

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
)
)

没有必要留下JOIN utV表。在发布该表之前,您应该测试您的假设comment@Vasily-您的代码可以工作,但是您能解释一下为什么需要coalesce命令吗?没有它,我会得到“你的查询在第三次检查数据库时失败”,这是我自己得到的。我不明白我的问题是什么,为什么我需要使用coalesce。@davidefaeli
coalesce
函数是删除
null
所必需的(类似于
NULLIF
ISNULL
,但我使用它是因为习惯,而且它相对于其他
null
转换函数也有一些优势)如果
UQ.Q_ID
UB.B_Q_ID
不匹配。因此,如果这两个匹配键不匹配,
合并
将返回
0
,在下一次计算中,这意味着每平方米的平均油漆量将等于
0
(因为表
utB
中没有关于某些平方米的“油漆量”的数据)@daviderfaeli
sql ex
是一个非常有趣的资源,不仅因为您有机会获得有关如何在
tsql
上编写查询的知识,还将有机会获得如何在“盲”模式下处理数据的经验,这意味着您键入的查询对数据可用性和一致性一无所知(如果您认为您的代码是完美的,但在某些服务器上没有返回正确的结果,那么您应该应用“假设”并更改代码以获得所需的结果)