从 CTE 表达式的结果中获取不同的行
Get different rows from result of CTE expression
我有这样的 CTE:
DECLARE @LastDesigns AS TABLE
(
[LegacyKey] INT
, [DesignKey] INT
, [Folio] INT
, [StatusKey] INT
, [DesignGroupId] UNIQUEIDENTIFIER
)
INSERT INTO @LastDesigns
SELECT
[P].[LegacyKey]
, [D].[DesignKey]
, [D].[Folio]
, [D].[StatusKey]
, [D].[DesignGroupId]
FROM EbCorp.dbo.Project AS P
INNER JOIN EbCorp.dbo.DesignGroup AS DG ON P.ProjectKey = DG.ProjectKey
INNER JOIN EbCorp.dbo.Design AS D ON DG.DesignGroupId = D.DesignGroupId
WHERE [D].[IsDeleted] = 0
AND [ParentDesignGroupId] IS NULL;
WITH CTE2 (
[LegacyKey]
, [DesignKey]
, [Folio]
, [StatusKey]
, [DesignGroupId]
, [RN]
) AS (
SELECT
[LegacyKey]
, [DesignKey]
, [Folio]
, [StatusKey]
, [DesignGroupId]
, ROW_NUMBER() OVER(PARTITION BY [LegacyKey], [DesignGroupId] ORDER BY [DesignKey] DESC) AS [RN]
FROM @LastDesigns
)
SELECT
[LegacyKey]
, [DesignKey]
, [Folio]
, [StatusKey]
, [DesignGroupId]
FROM CTE2
WHERE [RN] = 1;
此查询returns信息如下:
+-----------+-----------+-------+-----------+--------------------------------------+
| LegacyKey | DesignKey | Folio | StatusKey | DesignGroupId |
+-----------+-----------+-------+-----------+--------------------------------------+
| 18233 | 7540 | 5465 | 67 | 25687D54-B109-451B-9386-DD21C24ABBA9 |
| 18233 | 7543 | 5464 | 67 | 25687D54-B109-451B-9386-DD21C24ABBA9 |
| 18233 | 5229 | 4104 | 111 | 7E9F6DC9-6D1F-40DA-9D84-FE4D969A4289 |
| 18234 | 3920 | 2792 | 67 | 44D2DAFB-1880-4B93-AD04-2336B43E5BCA |
| 18234 | 7381 | 5306 | 67 | 7ADF74D6-A915-4882-9AC4-80FD801E9570 |
+-----------+-----------+-------+-----------+--------------------------------------+
我们只关注 2 列:LegacyKey
和 StatusKey
如您所见,前三行具有相同的 LegacyKey
,但其中一行具有不同的 StatusKey
。
我只想要 LegacyKey
其中一个 StatusKey
是 67
并且相同的 LegacyKey
有另一行 StatusKey
的 67
,这可能吗?
所以在上面的例子中我只想要
18233 | 5229 | 4104 | 111 | 7E9F6DC9-6D1F-40DA-9D84-FE4D969A4289 |
因为此 LegacyKey
有另一行 StatusKey
的 67
并且最后两行是相同的 LegacyKey 但都具有 67
和 StatusKey
所以我不要了。
一个simple/easy理解方法:
SELECT *
FROM cte
WHERE
statuskey <> 67 and
legacykey in (SELECT legacykey FROM cte WHERE statuskey= 67)
这将构建状态键为 67 的所有 legacykeys 的列表,然后查找状态键不是 67 但在该构建列表中确实具有 legacykey 的所有行
这也可以通过连接、存在甚至分组来完成,但对我来说,IN 方法可能最容易阅读、理解和维护
我有这样的 CTE:
DECLARE @LastDesigns AS TABLE
(
[LegacyKey] INT
, [DesignKey] INT
, [Folio] INT
, [StatusKey] INT
, [DesignGroupId] UNIQUEIDENTIFIER
)
INSERT INTO @LastDesigns
SELECT
[P].[LegacyKey]
, [D].[DesignKey]
, [D].[Folio]
, [D].[StatusKey]
, [D].[DesignGroupId]
FROM EbCorp.dbo.Project AS P
INNER JOIN EbCorp.dbo.DesignGroup AS DG ON P.ProjectKey = DG.ProjectKey
INNER JOIN EbCorp.dbo.Design AS D ON DG.DesignGroupId = D.DesignGroupId
WHERE [D].[IsDeleted] = 0
AND [ParentDesignGroupId] IS NULL;
WITH CTE2 (
[LegacyKey]
, [DesignKey]
, [Folio]
, [StatusKey]
, [DesignGroupId]
, [RN]
) AS (
SELECT
[LegacyKey]
, [DesignKey]
, [Folio]
, [StatusKey]
, [DesignGroupId]
, ROW_NUMBER() OVER(PARTITION BY [LegacyKey], [DesignGroupId] ORDER BY [DesignKey] DESC) AS [RN]
FROM @LastDesigns
)
SELECT
[LegacyKey]
, [DesignKey]
, [Folio]
, [StatusKey]
, [DesignGroupId]
FROM CTE2
WHERE [RN] = 1;
此查询returns信息如下:
+-----------+-----------+-------+-----------+--------------------------------------+
| LegacyKey | DesignKey | Folio | StatusKey | DesignGroupId |
+-----------+-----------+-------+-----------+--------------------------------------+
| 18233 | 7540 | 5465 | 67 | 25687D54-B109-451B-9386-DD21C24ABBA9 |
| 18233 | 7543 | 5464 | 67 | 25687D54-B109-451B-9386-DD21C24ABBA9 |
| 18233 | 5229 | 4104 | 111 | 7E9F6DC9-6D1F-40DA-9D84-FE4D969A4289 |
| 18234 | 3920 | 2792 | 67 | 44D2DAFB-1880-4B93-AD04-2336B43E5BCA |
| 18234 | 7381 | 5306 | 67 | 7ADF74D6-A915-4882-9AC4-80FD801E9570 |
+-----------+-----------+-------+-----------+--------------------------------------+
我们只关注 2 列:LegacyKey
和 StatusKey
如您所见,前三行具有相同的 LegacyKey
,但其中一行具有不同的 StatusKey
。
我只想要 LegacyKey
其中一个 StatusKey
是 67
并且相同的 LegacyKey
有另一行 StatusKey
的 67
,这可能吗?
所以在上面的例子中我只想要
18233 | 5229 | 4104 | 111 | 7E9F6DC9-6D1F-40DA-9D84-FE4D969A4289 |
因为此 LegacyKey
有另一行 StatusKey
的 67
并且最后两行是相同的 LegacyKey 但都具有 67
和 StatusKey
所以我不要了。
一个simple/easy理解方法:
SELECT *
FROM cte
WHERE
statuskey <> 67 and
legacykey in (SELECT legacykey FROM cte WHERE statuskey= 67)
这将构建状态键为 67 的所有 legacykeys 的列表,然后查找状态键不是 67 但在该构建列表中确实具有 legacykey 的所有行
这也可以通过连接、存在甚至分组来完成,但对我来说,IN 方法可能最容易阅读、理解和维护