2017-08-17 63 views
1

我需要按UniqueIdentifier列進行分組,該表還包含XML列。如何按列分組 - SQL Server

表模式:StudentMark

CREATE TABLE [dbo].[StudentMark] 
(
    [StudentMarkId] [int] IDENTITY(1,1) NOT NULL, 
    [StudentId] [uniqueidentifier] NULL, 
    [SubjectId] [uniqueidentifier] NULL, 
    [ScoreInfo] [xml] NULL, 
    [GeneratedOn] [datetime2](2) NOT NULL, 

    CONSTRAINT [PK_StudentMark] 
     PRIMARY KEY CLUSTERED ([StudentMarkId] ASC) 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

樣品種子數據

INSERT INTO [dbo].[StudentMark] ([StudentId], [SubjectId], [ScoreInfo], GeneratedOn]) 
VALUES ('FC3CB475-B480-4129-9190-6DE880E2D581', '0D72F79E-FB48-4D3E-9906-B78A9D105081', '<StudentMarkAttribute xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></StudentMarkAttribute>', '2017-08-10 10:20:15'), 
     ('0F4EF48C-93E3-41AA-8295-F6B0E8D8C3A2', '0D72F79E-FB48-4D3E-9906-B78A9D105081', '<StudentMarkAttribute xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></StudentMarkAttribute>', '2017-08-10 10:20:15'), 
     ('0F4EF48C-93E3-41AA-8295-F6B0E8D8C3A2', 'AB172272-D2E9-49E1-8040-6117BB6743DB', '<StudentMarkAttribute xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></StudentMarkAttribute>', '2017-08-16 09:06:20'), 
     ('FC3CB475-B480-4129-9190-6DE880E2D581', 'AB172272-D2E9-49E1-8040-6117BB6743DB', '<StudentMarkAttribute xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></StudentMarkAttribute>', '2017-08-16 09:06:20'); 

要求:我需要按[dbo].[StudentMark].[StudentId]採取的最新記錄。

我嘗試以下SQL查詢,但它造成的錯誤

SELECT 
    MAX([StudentMarkId]), [StudentId], [SubjectId], [ScoreInfo], [GeneratedOn] 
FROM 
    [dbo].[StudentMark] 
GROUP BY 
    [StudentId] 

錯誤

列「dbo.StudentMark.SubjectId」是因爲它是在選擇列表中無效不包含在聚合函數或GROUP BY子句中。

我審閱了以下問題,但我不能修復:Reason for Column is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

請幫助我。

SELECT * 
FROM (
    SELECT *, 
     ROW_NUMBER() OVER(PARTITION BY StudentId ORDER BY StudentMarkId DESC) AS rn 
    FROM [dbo].[StudentMark]) sub 
WHERE sub.rn = 1; 

回答

3

使用ROW_NUMBER到組內計算出位置

select sm.* 
from students s cross apply 
    (select top 1 sm.* 
     from studentmark sm 
     where sm.studentid = s.studentid 
     order by sm.generatedon desc 
    ) sm; 
+0

請您確認一下,我們不能使用「分組依據」?而不是'Row_Number'方法? –

+0

@ B.Balamanigandan您不能以您建議的方式使用GROUP BY。你的問題很清楚,「每組最大的第n個」 – lad2025

+0

你能否確認哪一個答案更可取?在優化方面的兩個答案? –

1

另一種解決方案效果最好,如果你有一個Students表:

+0

您能否確認一下,您最好採用哪種方法或'Row_Number'方法?哪一個是有效的? –

+0

@ B.Balamanigandan。 。 。你應該嘗試一下你的數據,看看哪個更好。用'studentmark(studentid,generatedon)'的索引,我預計這會稍微快一點。 –

0

你不能XMLTEXT列組,你會先需要轉換爲varchar(max)

SELECT 
    MAX([StudentMarkId]), [StudentId], [SubjectId], 
    CONVERT(XML, CONVERT(VARCHAR(MAX), [ScoreInfo])) DetailXML, 
    [GeneratedOn] 
FROM 
    [dbo].[StudentMark] 
GROUP BY 
    [StudentId], [SubjectId], 
    CONVERT(VARCHAR(MAX), [ScoreInfo]), [GeneratedOn] 

在第一行,它被轉換爲varchar(max)以匹配GROUP BY子句,隨後將其重新轉換回XML。

+0

它返回所有四條記錄。 –