Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
201 views
in Technique[技术] by (71.8m points)

sql - Get last row of each group with CTE

I have a query like this:

DECLARE @DeadDesigns AS TABLE(
 LegacyKey INT
,DesignKey INT
,StatusKey INT
,DesignGroupId UNIQUEIDENTIFIER
)
INSERT INTO @DeadDesigns
SELECT [P].[LegacyKey],[D].DesignKey, [D].[StatusKey], [D].[DesignGroupId] FROM Project AS P
INNER JOIN DesignGroup AS DG ON P.ProjectKey = DG.ProjectKey
INNER JOIN Design AS D ON DG.DesignGroupId  = D.DesignGroupId
WHERE [D].[StatusKey] = 67 --DEAD 

;WITH CTE2 (LegacyKey, DesignKey, StatusKey, DesignGroupId, RN) AS (
SELECT LegacyKey, DesignKey, StatusKey, DesignGroupId,
ROW_NUMBER() OVER (PARTITION BY [LegacyKey], [DesignGroupId] ORDER BY [DesignGroupId]) AS RN
FROM @DeadDesigns 
    GROUP BY [DesignGroupId],[LegacyKey],DesignKey,StatusKey
)
SELECT * FROM CTE2

Structure is:

One LegacyKey can have multiple DesignGroupId and one DesignGroupId can have multiple DesignKey

Objective is to get last DesignKey of each DesignGroupId separated from project

Wrong result:

+-----------+-----------+-----------+--------------------------------------+----+
| LegacyKey | DesignKey | StatusKEy |            DesignGroupId             | RN |
+-----------+-----------+-----------+--------------------------------------+----+
|     14002 |      2416 |        67 | 1A07C80E-E5E2-45F0-A5D2-419BAF3DC106 |  1 |
|     14002 |      2819 |        70 | 1A07C80E-E5E2-45F0-A5D2-419BAF3DC106 |  2 |
+-----------+-----------+-----------+--------------------------------------+----+

This is wrong because it is the same DesignGroupId, if that DesignGroupId was different result was correct.

Detailed desire result:

I want to separate it by DesignGroupId so if have two different DesignGroupId and it's the same LegacyKey RN of second row should be 2.. if we have 3 DesignGroupId but same LegacyKey RN of second row should be 3 and so on. At the end I want to get ALL last DesignKey inside each DesignGroupId inside each LegacyKey

What am I doing wrong?

Another example

+-----------+-----------+-----------+--------------------------------------+----+
| LegacyKey | DesignKey | StatusKEy |            DesignGroupId             | RN |
+-----------+-----------+-----------+--------------------------------------+----+
|     18288 |      3974 |        63 | F18320D8-C7A8-4A2A-AFDE-38A483C24E81 |  1 |
|     18288 |      4096 |       107 | F18320D8-C7A8-4A2A-AFDE-38A483C24E81 |  2 |
|     18288 |      7224 |        66 | F18320D8-C7A8-4A2A-AFDE-38A483C24E81 |  3 |
|     18288 |      4842 |        66 | A18320D8-C7A8-4A2A-AFDE-38A483C24E81 |  1 |
|     18289 |      7325 |        66 | 90C224D9-2514-4294-8DEC-D3EE16EC2D00 |  1 |
|     18289 |      3975 |        63 | 90C224D9-2514-4294-8DEC-D3EE16EC2D00 |  2 |
+-----------+-----------+-----------+--------------------------------------+----+

In this case I have two different LegacyKey but result is wrong because it returns all RN of same DesignGroupId and I only want last one. Desire result is:

+-----------+-----------+-----------+--------------------------------------+----+
| LegacyKey | DesignKey | StatusKEy |            DesignGroupId             | RN |
+-----------+-----------+-----------+--------------------------------------+----+
|     18288 |      7224 |        66 | F18320D8-C7A8-4A2A-AFDE-38A483C24E81 |  3 |
|     18288 |      4842 |        66 | A18320D8-C7A8-4A2A-AFDE-38A483C24E81 |  1 |
|     18289 |      3975 |        63 | 90C224D9-2514-4294-8DEC-D3EE16EC2D00 |  2 |
+-----------+-----------+-----------+--------------------------------------+----+

As you can see I get last RN of DesignGroupId, but they are in the same LegacyKey

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I would not expect a GROUP BY in the subquery. And I would expect filtering in the outer query:

WITH CTE2 (LegacyKey, DesignKey, StatusKey, DesignGroupId, RN) AS (
      SELECT LegacyKey, DesignKey, StatusKey, DesignGroupId,
             ROW_NUMBER() OVER (PARTITION BY [LegacyKey], [DesignGroupId] ORDER BY [DesignGroupId] DESC) AS seqnum
      FROM @DeadDesigns 
     )
SELECT *
FROM CTE2
WHERE seqnum = 1;

Note that I changed the ORDER BY to DESC -- that is typical when you want the "last" or "most recent" of something.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...