各种标记范围内的标记百分比

时间:2014-11-02 10:35:32

标签: sql tsql percentage

我有一张看起来像这样的表

enter image description here

对于每个评估代码,我想创建一个查询,该查询返回某些标记范围内的标记百分比...例如

 FileYear   AssessmentCode   MarkRange   MarkPercentage

   2014        11cpssdd        0-10           5.88
   2014        11cpssdd        11-20          0
   2014        11cpssdd        21-30          0
   2014        11cpssdd        31-40          0
   2014        11cpssdd        41-50          0
   2014        11cpssdd        51-60          0
   2014        11cpssdd        61-70          0
   2014        11cpssdd        71-80          29.4
   2014        11cpssdd        81-90          52.9
   2014        11cpssdd        91-100         11.7

根本不确定如何做到这一点,并想知道是否有人能够提供帮助?提前感谢您的帮助。

5 个答案:

答案 0 :(得分:1)

您可以计算每个范围的SUM,然后计算整个SUM中此SUM的百分比。这是完整的工作示例:

SET NOCOUNT ON
GO

    DECLARE @DataSource TABLE
    (
         [FileYear] CHAR(4)
        ,[AssessmentCode] CHAR(8)
        ,[StudentID] INT
        ,[Mark] TINYINT
    )   

    INSERT INTO @DataSource ([FileYear], [AssessmentCode], [StudentID], [Mark])
    VALUES ('2014', '11cpssdd', '34323', '75')
          ,('2014', '11cpssdd', '74666', '38')
          ,('2014', '11cpssdd', '87664', '34')
          ,('2014', '11cpssdd', '87576', '66')
          ,('2014', '11cpssdd', '23455', '87')
          ,('2014', '11cpssdd', '87654', '75')
          ,('2014', '11cpssdd', '98776', '75')
          ,('2014', '11cpssdd', '34543', '55')
          ,('2014', '11ecoeco', '87687', '89')
          ,('2014', '11ecoeco', '56466', '77')
          ,('2014', '11ecoeco', '34544', '45')
          ,('2014', '11ecoeco', '95554', '23')
          ,('2014', '11ecoeco', '22322', '56')
          ,('2014', '11ecoeco', '76557', '66')

    SELECT [FileYear]
          ,[AssessmentCode]
          ,[MarkPercentage]
          ,[MarkRange] * 100 /[ALL] AS [MarkRange]
    FROM
    (
        SELECT [FileYear]
              ,[AssessmentCode]
              ,SUM(IIF([Mark] BETWEEN 0 AND 10, [Mark], 0)) 
              ,SUM(IIF([Mark] BETWEEN 11 AND 20, [Mark], 0)) 
              ,SUM(IIF([Mark] BETWEEN 21 AND 30, [Mark], 0)) 
              ,SUM(IIF([Mark] BETWEEN 31 AND 40, [Mark], 0))
              ,SUM(IIF([Mark] BETWEEN 41 AND 50, [Mark], 0))
              ,SUM(IIF([Mark] BETWEEN 51 AND 60, [Mark], 0))
              ,SUM(IIF([Mark] BETWEEN 61 AND 70, [Mark], 0)) 
              ,SUM(IIF([Mark] BETWEEN 71 AND 80, [Mark], 0)) 
              ,SUM(IIF([Mark] BETWEEN 81 AND 90, [Mark], 0))
              ,SUM(IIF([Mark] BETWEEN 91 AND 100, [Mark], 0)) 
              ,SUM([Mark])
        FROM @DataSource
        GROUP BY [FileYear]
                ,[AssessmentCode]
    ) DataSource ([FileYear], [AssessmentCode], [0-10], [11-20], [21-30], [31-40], [41-50], [51-60], [61-70], [71-80], [81-90], [91-100], [ALL])
    UNPIVOT
    (
        [MarkRange] FOR [MarkPercentage] IN ([0-10], [11-20], [21-30], [31-40], [41-50], [51-60], [61-70], [71-80], [81-90], [91-100])
    )PVT
    ORDER BY [FileYear]
            ,[AssessmentCode]
            ,[MarkPercentage]

SET NOCOUNT OFF
GO

enter image description here


检查此解决方案。请注意我们正在筛选特定的AssesmentCode。另外,如果您需要decimal格式的结果,只需在分割前投射[MarkRange]

SET NOCOUNT ON
GO

    DECLARE @DataSource TABLE
    (
         [FileYear] CHAR(4)
        ,[AssessmentCode] CHAR(8)
        ,[StudentID] INT
        ,[Mark] TINYINT
    )   

    INSERT INTO @DataSource ([FileYear], [AssessmentCode], [StudentID], [Mark])
    VALUES ('2014', '11CPSSDD', '34323', '93')
          ,('2014', '11CPSSDD', '74666', '93')
          ,('2014', '11CPSSDD', '87664', '90')
          ,('2014', '11CPSSDD', '87576', '90')
          ,('2014', '11CPSSDD', '23455', '89')
          ,('2014', '11CPSSDD', '87654', '86')
          ,('2014', '11CPSSDD', '98776', '84')
          ,('2014', '11CPSSDD', '34543', '84')
          ,('2014', '11CPSSDD', '87687', '84')
          ,('2014', '11CPSSDD', '56466', '83')
          ,('2014', '11CPSSDD', '34544', '82')
          ,('2014', '11CPSSDD', '95554', '80')
          ,('2014', '11CPSSDD', '22322', '79')
          ,('2014', '11CPSSDD', '76557', '78')
          ,('2014', '11CPSSDD', '76557', '77')
          ,('2014', '11CPSSDD', '76557', '76')
          ,('2014', '11CPSSDD', '76557', '70')

    SELECT [FileYear]
          ,[AssessmentCode]
          ,[MarkPercentage]
          ,[MarkRange] * 100 /[ALL] AS [MarkRange]
    FROM
    (
        SELECT [FileYear]
              ,[AssessmentCode]
              ,SUM(IIF([Mark] BETWEEN 0 AND 10, 1, 0)) 
              ,SUM(IIF([Mark] BETWEEN 11 AND 20, 1, 0)) 
              ,SUM(IIF([Mark] BETWEEN 21 AND 30, 1, 0)) 
              ,SUM(IIF([Mark] BETWEEN 31 AND 40, 1, 0))
              ,SUM(IIF([Mark] BETWEEN 41 AND 50, 1, 0))
              ,SUM(IIF([Mark] BETWEEN 51 AND 60, 1, 0))
              ,SUM(IIF([Mark] BETWEEN 61 AND 70, 1, 0)) 
              ,SUM(IIF([Mark] BETWEEN 71 AND 80, 1, 0)) 
              ,SUM(IIF([Mark] BETWEEN 81 AND 90, 1, 0))
              ,SUM(IIF([Mark] BETWEEN 91 AND 100, 1, 0)) 
              ,COUNT([Mark])
        FROM @DataSource
        WHERE [AssessmentCode] = '11CPSSDD'
        GROUP BY [FileYear]
                ,[AssessmentCode]
    ) DataSource ([FileYear], [AssessmentCode], [0-10], [11-20], [21-30], [31-40], [41-50], [51-60], [61-70], [71-80], [81-90], [91-100], [ALL])
    UNPIVOT
    (
        [MarkRange] FOR [MarkPercentage] IN ([0-10], [11-20], [21-30], [31-40], [41-50], [51-60], [61-70], [71-80], [81-90], [91-100])
    )PVT
    ORDER BY [FileYear]
            ,[AssessmentCode]
            ,[MarkPercentage]

SET NOCOUNT OFF
GO

答案 1 :(得分:0)

您可以使用CASE语句来有条件地选择您需要的内容。你需要一个用于MarkRange列,一个用于返回MarkPercentage。

请参阅http://msdn.microsoft.com/en-us/library/ms181765.aspx

答案 2 :(得分:0)

这不是确切的答案,但这应该对你有所帮助我不知道你是如何得到这个百分比的。所以我评论说你可以稍微调整一下来获得百分比。

CREATE TABLE #test
  (
     FileYear       INT,
     AssessmentCode VARCHAR(50),
     StudentID      INT,
     Mark           INT
  )

INSERT INTO #test
VALUES      ( 2014,'11cpssdd',34323,75),( 2014,'11cpssdd',74666,38 ),
            ( 2014,'11cpssdd',87664,34),( 2014,'11cpssdd',87576,66),
            ( 2014,'11cpssdd',23455,87),( 2014,'11cpssdd',87654,75),
            ( 2014,'11cpssdd',98776,75),( 2014,'11cpssdd',34543,55),
            ( 2014,'11ecoeco',87687,89),( 2014,'11ecoeco',56466,77),
            ( 2014,'11ecoeco',34544,45),( 2014,'11ecoeco',95554,23),
            ( 2014,'11ecoeco',22322,56),( 2014,'11ecoeco',76557,66) 

;WITH cte
     AS (SELECT DISTINCT 0  AS fst,
                         10 AS scd,
                         fileyear,
                         AssessmentCode
         FROM   #test
         WHERE  AssessmentCode = '11cpssdd'
         UNION ALL
         SELECT scd + 1 fst,
                scd + 10,
                fileyear,
                AssessmentCode
         FROM   cte
         WHERE  scd < 100)
SELECT b.FileYear,
       b.AssessmentCode,
       CONVERT(VARCHAR(10), fst) + ' - '
       + CONVERT(VARCHAR(10), scd) MarkRange,
       count(case when mark IS not null then 1 end) Range_Count
       --(count(case when mark IS not null then 1 end)/10.0)*100 percentage
FROM   cte b
       LEFT JOIN(SELECT CASE
                          WHEN mark BETWEEN 0 AND 10 THEN '0 - 10'
                          WHEN mark BETWEEN 11 AND 20 THEN '11 - 20'
                          WHEN mark BETWEEN 21 AND 30 THEN '21 - 30'
                          WHEN mark BETWEEN 31 AND 40 THEN '31 - 40'
                          WHEN mark BETWEEN 41 AND 50 THEN '41 - 50'
                          WHEN mark BETWEEN 51 AND 60 THEN '51 - 60'
                          WHEN mark BETWEEN 61 AND 70 THEN '61 - 70'
                          WHEN mark BETWEEN 71 AND 80 THEN '71 - 80'
                          WHEN mark BETWEEN 81 AND 90 THEN '81 - 90'
                          WHEN mark BETWEEN 90 AND 100 THEN '90 - 100'
                        END [range],
                        FileYear,
                        mark,
                        AssessmentCode
                 FROM   #test
                 WHERE  AssessmentCode = '11cpssdd') a
              ON CONVERT(VARCHAR(10), fst) + ' - '
                 + CONVERT(VARCHAR(10), scd) = [range]
                 AND a.AssessmentCode = b.AssessmentCode
GROUP  BY b.FileYear,
          b.AssessmentCode,
          CONVERT(VARCHAR(10), b.fst) + ' - '
          + CONVERT(VARCHAR(10), b.scd) 

答案 3 :(得分:0)

  1. 为特定范围声明每个变量10个。
  2. 将光标放在&#39; MARK&#39;并将相对变量增加1。
  3. 算一算。变量=变量/ 17。
  4. 分别将变量更新为新列&#39; MARK RANGE&#39;。
  5. 祝你好运!!

答案 4 :(得分:0)

这是获得结果的另一种方法。

;WITH a AS
(
    SELECT FileYear, AssessmentCode, MarkCount = COUNT(*)
    FROM #1
    GROUP BY FileYear, AssessmentCode
)
, b AS
(
    SELECT FileYear, AssessmentCode, Tenth = (Mark - 1)/10 + 1, MarkCount = COUNT(*)
    FROM #1
    GROUP BY FileYear, AssessmentCode, (Mark - 1)/10 + 1
)
SELECT a.FileYear, a.AssessmentCode
, MarkPercentage = CONVERT(varchar(3), Tenth * 10 - IIF(Tenth=1,10,9)) + '-'
                   + CONVERT(varchar(3), Tenth * 10)
, MarkRange = CONVERT(float, LEFT(100.0 * b.MarkCount / a.MarkCount, 4))
FROM a
JOIN b ON a.FileYear = b.FileYear AND a.AssessmentCode = b.AssessmentCode
ORDER BY a.FileYear, a.AssessmentCode