2014-09-04 153 views
2

我有3个不同的表(table1,table2,table3),我需要执行百分比和频率操作并输​​出一个HTML表格。左连接3表

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

我需要出去放一张桌子,看起来像这样

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和catCode(table1)的%。问题是我如何添加其他两个表格和频率。

$sqlCom = "select CatCodes1, CAST(count(*) * 100.0/sum(count(*)) over()"; 
$sqlCom .= " AS DECIMAL(18,2)) from table1 group by CatCodes1"; 
+0

你试图UNION ALL? http://msdn.microsoft.com/en-us/library/ms180026.aspx – 2014-09-04 21:43:27

回答

3

让我们试试这个。你需要做计算作为子查询。另外,您需要一个内部查询来计算数据集中包含的记录数量。然后有一个外部查询将所有内容连接在一起。

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是做任何其他的解释...

+0

是的,因为某些原因,我没有得到两个表的百分比。有点奇怪。我的SQL技能很低。试图获得它们,但可以让他们在一夜之间:( – user3527285 2014-09-05 20:34:22

+1

我想出了零和更新代码的原因,这应该可以帮助你解决问题 – laughsloudly 2014-09-05 22:55:41

+0

哇,你是一个天才,是的,我有几个问题。这些ttl.t2Ttl和他们究竟在干什么?还有,这些百分比并不是四舍五入到小数点后两位。还有两列值相同的额外列是什么?另外,我们是否使用表2中的测试= 1条件?这就像在哪里测试= 1 – user3527285 2014-09-06 16:54:13

0

,看一下这个页面http://sqlpro.developpez.com/cours/sqlaz/jointures/ 对不起,这是法语,但阅读包含代码“加入”可能会帮助你。

首先,试图在没有任何计算的情况下提取3个表上的数据。 并显示:

echo '<pre>'; 
print_r($result); 
echo '</pre>'; 

那么当结果表是好的,加上计算。

3

我相信这会做的伎俩......你需要做的计算作为子查询和有一个外部查询来加入一切。

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)', ISNULL(t2.myPercent, 0) AS 'Percentage(tab2)', 
    ISNULL(t3.CountOfCodesCatAll, 0) AS 'Freq in CodesCatAll(tab3)', ISNULL(t3.myPercent, 0) 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 myPercent 
    FROM table2 
    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 myPercent 
    FROM table3 
    GROUP BY CodesCatAll 
) t3 ON t1.CatCodes1 = t3.CodesCatAll 
+0

percentagefrom tab2应该在所有CatCode(tab2)中使用Freq加起来最多为100%。在CodesCatAll(tab3)中使用Freq使用频率3中的百分比同样的东西(总计高达100%)。 很抱歉,如果不清楚。我编辑了我的问题一点点,以便它清楚 – user3527285 2014-09-05 16:23:03

+0

另外我怎么得到xxx和最后一行的yyy – user3527285 2014-09-05 16:46:56

+0

因此,“百分比(tab2)”中的百分比不应该包括表2中的所有行,但只有JOINED行在表2中?嗯,这更复杂。 – laughsloudly 2014-09-05 18:10:30