目前有一个脚本可以处理十几个SELECT语句,其中两个示例以及结果示例如下所示。
DECLARE @Age TABLE (name VARCHAR(30), total FLOAT, percentage FLOAT)
INSERT INTO @Age
SELECT '0-18', (SELECT COUNT(*) FROM tblPerson p
INNER JOIN tblClient c ON c.intPersonID = p.intPersonID
WHERE ISNULL(dbo.fncReportClient_Age(p.dteBirthdate, GETDATE()), '') >= 0 AND ISNULL(dbo.fncReportClient_Age(p.dteBirthdate, GETDATE()), '') <= 18), ''
UPDATE @Age
SET percentage = ROUND((SELECT total FROM @Age WHERE name = '0-18')/(SELECT SUM(total) FROM @Age) * 100, 2)
FROM @Age
WHERE name = '0-18'
Etc.
SELECT
g.nvhGenderName,
COUNT(*),
ROUND(COUNT(*) * 1.0 / SUM(COUNT(*)) OVER () * 100, 2)
FROM
tblClient c
LEFT JOIN tblPerson p ON p.intPersonID = c.intPersonID
LEFT JOIN tblGender g ON g.intGenderID = p.intGenderID
GROUP BY g.nvhGenderName
UNION ALL
SELECT * FROM @Age
以下结果示例:
Name | Total | % |
---------------------------------
Male | 6514 | 60.32 |
Female | 4285 | 39.68 |
0-18 | 279 | 1.58 |
19-24 | 1748 | 9.93 |
25-34 | 5423 | 30.80 |
35-64 | 9546 | 54.21 |
65+ | 614 | 3.50 |
我希望水平显示这些结果而不是垂直显示,我认为可以用PIVOT做到这一点,但从未真正使用它们。我希望如何显示数据的示例如下所示:
Gender | Total | % | Age | Total | % |
-------------------------------------------------------------
Male | 6514 | 60.32 | 0-18 | 279 | 1.58 |
Female | 4285 | 39.68 | 19-24 | 1748 | 9.93 |
| | | 25-34 | 5423 | 30.80 |
| | | 35-64 | 9546 | 54.21 |
| | | 65+ | 614 | 3.50 |
特别是我不确定如何使用数据透视表来组合需要它的多个(12)SELECT语句。
如何格式化这方面的任何帮助将非常感激。
答案 0 :(得分:0)
虽然我认为布局确实应该在其他地方实现,但以下内容可能适合您。很明显我无法测试它,如果没有测试的好处,那么:
WITH myCTE AS (
SELECT
COUNT(CASE WHEN oa.age >= 0 AND oa.age < 19 THEN p.intPersonID ELSE NULL END) c0019
, COUNT(CASE WHEN oa.age >= 19 AND oa.age < 25 THEN p.intPersonID ELSE NULL END) c1925
, COUNT(CASE WHEN oa.age >= 25 AND oa.age < 35 THEN p.intPersonID ELSE NULL END) c2535
, COUNT(CASE WHEN oa.age >= 35 AND oa.age < 65 THEN p.intPersonID ELSE NULL END) c3565
, COUNT(CASE WHEN oa.age >= 65 THEN p.intPersonID ELSE NULL END) c65on
, COUNT(CASE WHEN g.nvhGenderName = 'Male' THEN p.intPersonID ELSE NULL END) cmale
, COUNT(CASE WHEN g.nvhGenderName = 'Female' THEN p.intPersonID ELSE NULL END) cfemale
, COUNT(*) ctotal
FROM tblClient c
LEFT JOIN tblPerson p ON p.intPersonID = c.intPersonID
OUTER APPLY (
SELECT
dbo.fncReportClient_Age(p.dteBirthdate) AS age
) AS oa
LEFT JOIN tblGender g ON g.intGenderID = p.intGenderID
)
SELECT
ca.Gender, ca.Total2, ca.Pct, ca.Age, ca.Total2, ca.Pct2
FROM myCTE
CROSS APPLY (
VALUES
(1, 'Male' , t.cmale , (cmale * 100.0 / ctotal), '0-18', c0019, (c0019 * 100.0 / ctotal))
, (2, 'Female',t.cfemale,(cfemale * 100.0 / ctotal), '19-24', c1925, (c1925 * 100.0 / ctotal))
, (3, NULL,NULL,NULL, '25-34', c2535, (c2535 * 100.0 / ctotal))
, (4, NULL,NULL,NULL, '35-64', c3565, (c3565 * 100.0 / ctotal))
, (5, NULL,NULL,NULL, '65+' , c65on, (c65on * 100.0 / ctotal))
) AS ca (rn, Gender, Total2, Pct, Age, Total2, Pct2)
ORDER BY ca.rn
;
上述查询的第二部分(较低部分)使用了unpivoting
数据的技术,该技术将cross apply
与values
结合在一起,这使我们能够布局&#34;想要的最终结果的每一行逐行。
使用CTE
(上面的查询的上半部分)并不重要,可以将其移动到子查询中,但CTE
内的查询应该先独立试验并且它应该在一次传递数据时生成所需的所有数字(假设性别表不会干扰计数结果)。请注意,使用count(case expression here)
无需多个单独的查询。我怀疑你顺便不需要左连接,如果确实如此,你也可以将外部申请更改为交叉申请。请注意,apply用于执行您的函数,通过这样做,我们可以通过查询的其余部分中的别名引用该函数的结果(我使用&#34; age&#34;作为该别名)。
我不确定为什么在计算人员表时涉及客户表。我怀疑它不是必需的。如果我的怀疑是正确的,那么CTE细节可以被替换为:
SELECT
COUNT(CASE WHEN oa.age >= 0 AND oa.age < 19 THEN 1 ELSE NULL END) c0019
, COUNT(CASE WHEN oa.age >= 19 AND oa.age < 25 THEN 1 ELSE NULL END) c1925
, COUNT(CASE WHEN oa.age >= 25 AND oa.age < 35 THEN 1 ELSE NULL END) c2535
, COUNT(CASE WHEN oa.age >= 35 AND oa.age < 65 THEN 1 ELSE NULL END) c3565
, COUNT(CASE WHEN oa.age >= 65 THEN 1 ELSE NULL END) c65on
, COUNT(CASE WHEN g.nvhGenderName = 'Male' THEN 1 ELSE NULL END) cmale
, COUNT(CASE WHEN g.nvhGenderName = 'Feale' THEN 1 ELSE NULL END) cfemale
, COUNT(*) ctotal
FROM tblPerson p
CROSS APPLY (
SELECT
dbo.fncReportClient_Age(p.dteBirthdate) AS age
) AS oa
INNER JOIN tblGender g ON g.intGenderID = p.intGenderID
答案 1 :(得分:-1)
Create VIEW view_name AS
SELECT * FROM (
select ColumnName1,ColumnName2 from TableName
) as s
PIVOT (
Sum(ColumnName2)
FOR ColumnName3 in ("Row1","Row2","Row3"
)
) As pvt
DROP VIEW view_name;
Select * from view_name