显示所有一列的总和的唯一组合

时间:2014-07-17 14:38:22

标签: sql sql-server

编辑:对不起这里的含糊不清。实际问题:有没有更好的方法让SQL为我获得总和?

我可能会比我需要的更努力,但情况如下:

我正在为我工​​作的部门负责人创建人口统计信息列表。他们希望看到典型的人口统计信息。 (年龄,性别,种族,服务成员,第一次与我们,专业,学位等。)

然而,当我这样做时,我意识到美国人口普查委员会可以在任何时候改变我们的种族,所以报告必须在那时更新,也可以添加或删除主要和学位等级的内容。在教育部门。

所以我一直在寻找一种方法来编写一种显示来自Table的数据的方法,但是根据该表中具有相同区域的人数进行求和。听起来很奇怪,我可能会把它变得比我需要的更糟糕。 (我是在1948行代码,到目前为止还没有完成,所有这些行基本上都是复制/粘贴,有轻微变化)

我关于提取数据的说法非常完美。它可以正常显示我想要的年份范围。 (仅发布第一年,而不是第二年或第五年,因为它只是更改的日期范围)注意:这不是完整的SELECT状态,因为完全不需要这样做。列列表是必需的,但您并不真正关心数据来自何处或我如何过滤它

DECLARE @StartDate DATETIME 
DECLARE @EndDate DATETIME
DECLARE @StartDateLast DATETIME 
DECLARE @EndDateLast DATETIME
DECLARE @StartDateFive DATETIME 
DECLARE @EndDateFive DATETIME

DECLARE @State VARCHAR(2)
/*Current Year*/
SET @StartDate = '01/01/2013'
SET @EndDate = '12/31/2013'


CREATE TABLE #Demographics /*Table where the data will be processed andultimately displayed from */
(
demo_id INT IDENTITY(1,1) NOT NULL,
header VARCHAR(100),
subheader VARCHAR(100),
value_year1 NUMERIC,
percent_year1 DECIMAL(10,2),
value_year2 NUMERIC,
percent_year2 DECIMAL(10,2),
value_year5 NUMERIC,
percent_year5 DECIMAL(10,2)
)

SELECT s.ID
    ,g.Name AS [gender]
    , FLOOR(DATEDIFF(DAY,s.dob,GETDATE())/365.25) AS Age
    , st.Abbreviation
    , eg.Name
    ,f_ss.Name AS [StudentStatus]
    ,CASE 
        WHEN EnrollmentStatus.EnrollmentLevel = 'Full Time' THEN 'FT'
        WHEN EnrollmentStatus.EnrollmentLevel = 'Part Time' THEN 'PT'
        ELSE 'Unknown' END [Enrollment]
    ,FirstTime.result AS FirstTime
    ,major.[Abbreviation] AS [Abbreviation]
    ,major.Major
    ,mb.Name AS [ServiceBranch]
    ,FirstDegree.FirstDegree
INTO #DemoTemp1

FROM dbo.Student s
INNER JOIN studentdegree sd ON s.id = sd.StudentID
JOIN dbo.Gender g ON g.id = s.GenderID
INNER JOIN dbo.address ad ON s.AddressID = ad.ID
INNER JOIN dbo.state st ON ad.StateID = st.ID
LEFT JOIN dbo.EthnicGroup eg ON eg.ID = s.EthnicGroupID
LEFT JOIN dbo.MilitaryBranch mb ON mb.ID = s.MilitaryBranchID
JOIN Prospect p ON s.ID = p.StudentID 

所以我抓取数据,然后将其转储到3个临时表中,然后从它们中拉出来显示并存储在上面定义为#Demographics的另一个临时表中。

以下是最终如何显示结果集数据:

demo_id|   header | subheader     | value_year1| percent_year1
1          Gender:| Male          | 15195      | 62.00  
2                 | Female        | 9150       | 37.00  
3                 | Not Disclosed | 23         | 0.00   
4          Age:   | Under 18      | 2          | 0.00   
5                 | 18-20         | 142        | 0.00   
6                 | 21-25         | 1757       | 7.00   
7                 | 26-30         | 3815       | 15.00  

这是从临时表到#Demographics表的插入,现在看起来是我认为最终应该改变的区域,这样我就不会写出1050个学位组合,专业,年龄,什么不是。

年龄和性别很容易,它是学位水平和专业的结合,杀了我。我需要总共考虑大约750种组合。

当我接触到Degree / Majors之类的东西时,它看起来像这个组合:

INSERT INTO #Demographics
SELECT 
    ''
    ,'Graduate Certificate in Project Management'
    ,(SELECT SUM(CASE WHEN dt1.Abbreviation + ' ' + dt1.major ='Certificate Graduate Certificate in Project Management' THEN 1 ELSE 0 END) FROM #DemoTemp1 dt1)
    ,(SELECT ((SUM(CASE WHEN dt1.Abbreviation + ' ' + dt1.major ='Certificate Graduate Certificate in Project Management THEN 1 ELSE 0 END)*100) / COUNT(dt1.ID)) FROM #DemoTemp1 dt1)
FROM #DemoTemp1 dt1 WHERE dt1.Abbreviation + ' ' + dt1.major ='Certificate Graduate Certificate in Project Management GROUP BY (CASE WHEN dt1.Abbreviation + ' ' + dt1.major ='Certificate Graduate Certificate in Project Management THEN 1 ELSE 0 END)

对于每个学位水平(dt1.abbreviation)和专业(dt1.major)

,我一直在考虑并多次编辑它

我如何基本上采用dt1.Abbreviation +' ' + dt1.major组合并让SQL吐出学生的总和,而不用自己编写每个组合。使用结果集,我在上面发布了所需的格式


编辑:这就是我现在正在使用的。我只是调整PERC / Y2P / Y5P列来显示实际百分比而不是小数

SELECT DISTINCT(dt.Abbreviation + ' ' + m.Name) [Program]
,YearOne.Counts
,YearOne.Perc
,YearTwo.Counts [y2c]
,YearTwo.Perc [y2p]
,YearFive.Counts [y5c]
,YearFive.perc [y5p]

FROM degree d
INNER JOIN degreetype dt ON d.DegreeTypeID = dt.ID
INNER JOIN dbo.Majors m ON d.MajorID = m.id

OUTER APPLY (SELECT count(*) Counts
                ,CAST((CAST(COUNT(*)AS float) * 100) / CAST((SELECT count(dt2.id)FROM #DemoTemp1 dt2)AS float)as decimal(10,2))*100 Perc
                --,(SELECT count(dt2.id) [dude]FROM #DemoTemp1 dt2) perc2
                FROM #DemoTemp1 dt1
                WHERE dt1.[DegreeType]+' '+ dt1.Major = dt.name +' '+ m.name

                ) YearOne
OUTER APPLY (SELECT count(*) Counts
                ,CAST((CAST(COUNT(*)AS float) * 100) / CAST((SELECT count(dt3.id)FROM #DemoTemp2 dt3)AS float)as decimal(10,2))*100 Perc
                --,(SELECT count(dt2.id) [dude]FROM #DemoTemp1 dt2) perc2
                FROM #DemoTemp2 dt2
                WHERE dt2.[DegreeType]+' '+ dt2.Major = dt.name +' '+ m.name

                ) YearTwo
OUTER APPLY (SELECT count(*) Counts
                ,CAST((CAST(COUNT(*)AS float) * 100) / CAST((SELECT count(dt4.id)FROM #DemoTemp5 dt4)AS float)as decimal(10,2))*100 Perc
                --,(SELECT count(dt2.id) [dude]FROM #DemoTemp1 dt2) perc2
                FROM #DemoTemp5 dt5
                WHERE dt5.[DegreeType]+' '+ dt5.Major = dt.name +' '+ m.name

                ) YearFive
WHERE 1=1
AND d.Archived = 0 
GROUP BY (dt.Abbreviation + ' ' + m.Name), YearOne.Counts,       YearOne.Perc,YearTwo.Counts,YearTwo.Perc,YearFive.Counts   ,YearFive.perc
HAVING YearOne.Counts > 0

1 个答案:

答案 0 :(得分:0)

您可以将第一个查询更改为此类问题。这是同样的事情,而且更简单。

SELECT 
    'Gender'
    ,'Male'
    , count(*)
    , (COUNT(*) * 100) / COUNT(dt1.ID)
FROM #DemoTemp1 dt1 
WHERE dt1.gender = 'Male' 
GROUP BY dt1.gender

你可以在第二个做类似的事情。无需反复敲击同一个表来获取汇总数据。

行。经过一遍又一遍,我想我终于明白了你在问什么。

这样的事情对你来说是第二次查询吗?

SELECT 
    ''
    , dt1.Abbreviation + ' ' + dt1.major
    , count(*)
    , (count(*) * 100) / COUNT(dt1.ID))
FROM #DemoTemp1 dt1 
GROUP BY dt1.Abbreviation + ' ' + dt1.major