让我们试试这个。你需要做计算作为子查询。另外,您需要一个内部查询来计算数据集中包含的记录数量。然后有一个外部查询将所有内容连接在一起。
Original SQL Fiddle HERE.
Updated SQL Fiddle HERE.
Third updated SQL Fiddle HERE.
SELECT t1.CatCodes1 AS 'CatCode1(tab1)', t1.myPercent AS '% of CatCode(tab1)',
ISNULL(t2.CountOfAllCatCodes, 0) AS 'Freq in All CatCode(tab2)',
CASE
WHEN ttl.t2Ttl = 0 THEN 0
ELSE CAST(ISNULL(t2.CountOfAllCatCodes, 0) * 100.0/ttl.t2Ttl AS DECIMAL(18,2))
END AS 'Percentage(tab2)',
ISNULL(t3.CountOfCodesCatAll, 0) AS 'Freq in CodesCatAll(tab3)',
CASE
WHEN ttl.t3Ttl = 0 THEN 0
ELSE CAST(ISNULL(t3.CountOfCodesCatAll, 0) * 100.0/ttl.t3Ttl AS DECIMAL(18,2))
END AS 'Percentage(tab3)'
FROM (
SELECT CatCodes1, CAST(COUNT(*) * 100.0/SUM(COUNT(*)) OVER() AS DECIMAL(18,2)) AS myPercent
FROM table1
GROUP BY CatCodes1
) t1
LEFT OUTER JOIN (
SELECT AllCatCodes, COUNT(*) AS CountOfAllCatCodes, CAST(COUNT(*) * 100.0/SUM(COUNT(*)) OVER() AS DECIMAL(18,2)) AS myPercent2
FROM table2
WHERE ISNULL(Tested, 0) = 1
GROUP BY AllCatCodes
) t2 ON t1.CatCodes1 = t2.AllCatCodes
LEFT OUTER JOIN (
SELECT CodesCatAll, COUNT(*) AS CountOfCodesCatAll, CAST(COUNT(*) * 100.0/SUM(COUNT(*)) OVER() AS DECIMAL(18,2)) AS myPercent3
FROM table3
GROUP BY CodesCatAll
) t3 ON t1.CatCodes1 = t3.CodesCatAll
CROSS JOIN (
--Calculate total records which are matched...
SELECT SUM(ISNULL(t2.CountOfAllCatCodes, 0)) as t2Ttl, SUM(ISNULL(t3.CountOfCodesCatAll, 0)) AS t3Ttl
FROM (
SELECT CatCodes1
FROM table1
GROUP BY CatCodes1
) t1
LEFT OUTER JOIN (
SELECT AllCatCodes, COUNT(*) AS CountOfAllCatCodes
FROM table2
WHERE ISNULL(Tested, 0) = 1
GROUP BY AllCatCodes
) t2 ON t1.CatCodes1 = t2.AllCatCodes
LEFT OUTER JOIN (
SELECT CodesCatAll, COUNT(*) AS CountOfCodesCatAll
FROM table3
GROUP BY CodesCatAll
) t3 ON t1.CatCodes1 = t3.CodesCatAll
) ttl
注:由于某些原因SQL小提琴被计算 '百分比(TAB2)' 字段为零。我已经检查了代码并找不到错误,正如你所看到的,'百分比(tab3)'是用完全相同的方式编写的,并且正确评估。您还可以看到CountOfAllCatCodes的计算结果为2,ttl.t2Ttl的计算结果为4,结果应为50%。所以,我不知道。
要填充页面上的xxx和yyy字段,请在构建表时保持运行总计,或者分别引用t2Ttl和t3Ttl字段。
编辑:我想出了为什么一些百分数返回零。这是一个假设的类型铸造问题。注意百分比的原始计算是这样的:
ISNULL(t2.CountOfAllCatCodes, 0)/ttl.t2Ttl * 100.0
所以,INTEGER/INTEGER * DECIMAL - > [截尾整数] * DECIMAL - > DECIMAL。
或者,使用数字:2/4 * 100.0 - > 0 * 100.0 - > 0
通过稍稍切换式中,我更改假设数据类型:
ISNULL(t2.CountOfAllCatCodes, 0) * 100.0/ttl.t2Ttl
或者,如果我们想要的话,我们可以使用公式中的CAST或CONVERT语句来明确它。
为了回答您的评论中提出的问题:
如何停止从表1显示空值?
要解决这个问题,无论您何时从Table1中进行选择,都需要在SQL测试中为WHERE子句添加WHERE子句。假如你不想在CatCodes1字段为空值,这将是这样的:
SELECT [whatever]
FROM Table1
WHERE CatCodes1 IS NOT NULL
能否请您给我解释一下查询是干什么的?像案例陈述一样,交叉连接,我们有4个左外连接。
现在你做了基本的SQL理论上这可能是出路的范围为原来的问题,但在这里有云:
CASE语句用于为基于各种条件的区域评估多种可能性。请参阅CASE声明中的this link for Microsoft's documentation。在这种情况下,我使用CASE语句来防止“除零”错误。您会发现,如果分母值EVER有可能为零,我们希望在实际执行计算之前通过测试零来避免此错误。如果可用,我只使用IF类型语句:如果分母为零,则返回零,否则返回分子/分母。由于SQL没有内联IF语句,我们使用CASE语句代替。
CROSS JOIN是你需要非常小心的事情,但在这种情况下是合适的。我可以很容易地计算每个表中与t1.CatCodes1匹配的记录数,我可以很容易地计算出t2和t3表中有多少记录,但我无法获得匹配记录的准确数字。为了解决这个问题,我做了一个单独的查询,只计算匹配的记录(ttl表)。然后我将CROSS JOIN添加到此表中,以便我们查询中的每一行都可以访问计算。 ttl表格用作分母来计算总匹配记录的百分比。
LEFT OUTER JOIN用于获取一个表中的所有行,以及仅在第二个表中匹配的行。老实说,我猜测这是否是这种情况下的正确加入。它比INNER JOIN更安全,因为只要记录存在于我们的主表中,我们就会在我们的数据集中看到结果。但是,如果我们使用INNER JOIN,则需要在ALL THREE表中存在该ID以显示在我们的结果中。你可以找到更多info about LEFT OUTER JOINS here...
让我知道你需要什么样的SQL是做任何其他的解释...
你试图UNION ALL? http://msdn.microsoft.com/en-us/library/ms180026.aspx – 2014-09-04 21:43:27