SQL的日期第一中位数

时间:2014-10-05 09:07:09

标签: sql sql-server median

“SQL for Smarties”一书显示了用于计算Date的First Median的示例代码。

我把这个例子放在这里。 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?

1 个答案:

答案 0 :(得分: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时,子查询中的含义是您对subquerys权重列的引用。但是Temp1.weight将是父查询Temp1表。 这意味着,对于Temp1表中的每一行,它将执行查询Temp1的所有行的新查询,并检查当前行的值。 所以10行将像200行,然后当然使用正确的索引,所以实际的rowcount不需要那么糟糕。

你得到的原因

  

无法绑定多部分标识符“Temp1.weight”。

是因为你试图在没有外部查询的情况下运行内部查询,因此服务器不知道你对Temp1的意思。它只知道T1。