不同使用COUNT和GROUP

时间:2014-12-22 15:37:37

标签: sql sql-server sql-server-2008

与我之前发布的另一个问题很相似,但更复杂(我想!)。

我有一组表格:

表1

 StudentId   Student     Course
 1234567     J. Bloggs   ABC      
 1234567     J. Bloggs   ABC       
 2345678     T. Test     ABC       

表2

StudentId    Student       Module      Result      StartDate     EndDate
1234567      J. Bloggs     DEF         Fail        13/01/2014    13/03/2014
1234567      J. Bloggs     DEF         Pass        01/05/2014    15/07/2014
2345678      T. Test       DEF         Pass        13/01/2014    13/03/2014

我想要做的是让SQL返回,首先是学生在模块中尝试了多少次尝试,然后返回最新的EndDate和Result,这样的事情

Student     Course    Module      ModuleAttempts       Result       EndDate
J. Bloggs   ABC       ABC               2              Pass         15/07/2014
T. Test     ABC       ABC               1              Pass         13/03/2014

编辑:添加了初始表格布局

4 个答案:

答案 0 :(得分:3)

这应该做:

;WITH CTE AS
(
    SELECT  *,
            ModuleAttempts = COUNT(*) OVER(PARTITION BY Student, Module),
            RN = ROW_NUMBER() OVER(PARTITION BY Student, Module
                                   ORDER BY EndDate DESC)
    FROM dbo.YourTable
)
SELECT  Student,
        Course,
        Module,
        ModuleAttempts,
        Result,
        EndDate
FROM CTE
WHERE RN = 1;

SQLFIDDLE DEMO

答案 1 :(得分:0)

你去了:SQL Fiddle Demo

SELECT Student, Course, Module, 
(SELECT COUNT(*) FROM myTable t2 WHERE t2.Student = t1.Student) as ModuleAttempts, 
CASE WHEN CAST(MAX(CAST(RESULT as INT)) AS BIT) = 1 THEN 'PASS' ELSE 'Fail' END as Result,
MAX(EndDate) as EndDate
FROM MyTable t1
GROUP By Student, Course, Module

注意:

  • 结果是我的示例中的位列(Pass = 1,Failed = 0)
  • 声明: (SELECT COUNT(*)FROM myTable t2 WHERE t2.Student = t1.Student)应为t2.ID = t1.ID,而不是t2.Student = t1.Student。

答案 2 :(得分:0)

Lamak的答案是正确的,但由于结果只包含失败并通过以下查询也将有效。

    SELECT  Student,
            Course,
            Module,
           count(ModuleAttempts) as ModuleAttempts,
           max(Result) as Result,
--max(Result) will return "pass" (if pass exists) as it comes after fail in dictionary 
           max(EndDate) as EndDate
    from table
    group by Student,
            Course,
            Module

答案 3 :(得分:0)

这是您的示例数据

SELECT * INTO #TEMP FROM
(
SELECT 'J. Bloggs' Student,   'ABC' Course,   '13/01/2014' StartDate,    '13/03/2014' EndDate,     'ABC' Module,       'Fail' Result
UNION ALL
SELECT 'J. Bloggs',   'ABC',       '01/05/2014',    '15/07/2014',     'ABC',        'Pass'
UNION ALL
SELECT 'T. Test',     'ABC',       '13/01/2014',    '13/03/2014',     'ABC' ,       'Pass'
)TAB

现在我已采用StartDateEndDate对应Student以及Course

SELECT Student,Course,Module,ModuleAttempts,Result,CONVERT(VARCHAR(10),EndDateNew,103) EndDate
FROM
(
    SELECT *,
    ROW_NUMBER() OVER(PARTITION BY STUDENT,Course ORDER BY CAST(CONVERT(CHAR(10),CONVERT(DATETIME,LEFT(ENDDATE,10),105),101) AS DATE) DESC) RNO,
    COUNT(RESULT) OVER(PARTITION BY STUDENT,Course) ModuleAttempts,
    MIN(CAST(CONVERT(CHAR(10),CONVERT(DATETIME,LEFT(StartDate,10),105),101) AS DATE)) OVER(PARTITION BY STUDENT,Course) SD,
    MAX(CAST(CONVERT(CHAR(10),CONVERT(DATETIME,LEFT(ENDDATE,10),105),101) AS DATE)) OVER(PARTITION BY STUDENT,Course) EndDateNew  
    FROM #TEMP 
)TAB
WHERE RNO=1

如果您还想根据模块选择,请更改

 PARTITION BY STUDENT,Course

PARTITION BY STUDENT,Course,Module

<强> RESULT

enter image description here