我有 3 个不同的表(表 1、表 2、表 3),我需要执行百分比和频率运算并输出一个 HTML 表。
表1
CatCodes1 | CatCodes2 | CatCodes3
----------+-----------+----------
75287 | 20220 | 65656
78922 | 20852 | 56666
75287 | 20220 | 62892
78922 | 20852 | 55665
表2:应该只拉测试结果=1
AllCatCodes | Tested
-------------+---------
75287 | 1
78922 | 0
75287 | 0
78922 | 0
20220 | 1
62892 | 1
20852 | NULL
65656 | 1
表3
CodesCatAll |
------------+
75287 |
56666 |
65656 |
20220 |
我需要放一张看起来像这样的 table
CatCode1(tab1) | % of CatCode(tab1) | Freq in All CatCode(tab2) | Percentage(tab2) | Freq in CodesCatAll(tab3) | Percentage(tab3) |
75287
78922
78992
Total 100% xxx 100% yyy 100%
下面是我为获取 catcode1 和 %of catCode(table1) 而编写的代码。问题是如何添加其他两个表和频率。
$sqlCom = "select CatCodes1, CAST(count(*) * 100.0 / sum(count(*)) over()";
$sqlCom .= " AS DECIMAL(18,2)) from table1 group by CatCodes1";
最佳答案
让我们试试这个。您需要将计算作为子查询进行。此外,您需要一个内部查询来计算数据集中包含多少条记录。然后有一个外部查询将所有内容连接在一起。
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 Fiddle 将“百分比 (tab2)”字段计算为零。我已经上下检查了代码,但没有发现我的错误,正如您所看到的,“Percentage(tab3)”的编写方式完全相同并且计算正确。您还可以看到 CountOfAllCatCodes 的计算结果为 2,而 ttl.t2Ttl 为 4,结果应该为 50%。所以,我不知道。
要填写您页面上的 xxx 和 yyy 字段,请在构建表格时保留总计,或者分别引用 t2Ttl 和 t3Ttl 字段。
编辑: 我弄清楚了为什么有些百分比返回零。这是一个假定的类型转换问题。注意百分比的原始计算是这样的:
ISNULL(t2.CountOfAllCatCodes, 0)/ttl.t2Ttl * 100.0
因此,整数/整数 * 小数 --> [截断整数] * 小数 --> 小数。
或者,使用数字:2/4 * 100.0 --> 0 * 100.0 --> 0。
通过稍微改变公式,我改变了假定的数据类型:
ISNULL(t2.CountOfAllCatCodes, 0) * 100.0/ttl.t2Ttl
或者,如果我们愿意,我们可以在公式上使用 CAST 或 CONVERT 语句使其显式化。
回答您评论中提出的问题:
如何阻止表 1 显示空值?
要解决此问题,无论何时从表 1 中进行选择,都应在 SQL 测试 NULL 中添加一个 WHERE 子句。假设您不想在 CatCodes1 字段上使用 NULL 值,它会像这样:
SELECT [whatever]
FROM Table1
WHERE CatCodes1 IS NOT NULL
能否请您向我解释一下查询在做什么?与 case 语句、交叉连接一样,我们有 4 个左外部连接。
现在您正在学习基本的 SQL 理论,这可能超出了原始问题的范围,但是这里有:
CASE 语句用于根据各种条件评估一个字段的多种可能性。参见 this link for Microsoft's documentation在 CASE 语句上。在这种情况下,我使用 CASE 语句来防止“被零除”错误。你看,如果分母值 EVER 有可能为零,我们希望确保在实际执行计算之前通过测试零来防止此错误。如果可用,我将只使用 IF 类型语句:如果分母为零,则返回零,否则返回分子/分母。由于 SQL 没有内联 IF 语句,我们使用 CASE 语句代替。
CROSS JOIN 是您需要非常小心使用的东西,但在这种情况下是合适的。我可以很容易地计算出每个表中有多少条记录与 t1.CatCodes1 匹配,我可以很容易地计算出 t2 和 t3 表中存在多少条记录,但是我无法获得准确的匹配记录数仅有的。为了解决这个问题,我做了一个单独的查询,只计算匹配的记录(ttl 表)。然后我交叉连接到这个表,这样我们查询中的每一行都可以访问计算。 ttl 表用作分母来计算总匹配记录的百分比。
LEFT OUTER JOIN 用于获取一个表中的所有行,以及仅匹配第二个表中的行。老实说,我在猜测在这种情况下这是否是正确的连接。它比 INNER JOIN 更安全,因为只要主表中存在记录,我们就会在数据集中看到结果。但是,如果我们使用 INNER JOIN,则 ID 需要存在于所有三个表中才能显示在我们的结果中。您可以找到更多 info about LEFT OUTER JOINS here...
如果您需要对 SQL 正在做什么的任何其他解释,请告诉我...
关于php - 左连接 3 个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25674066/