【问题标题】:How to group this query to get required results如何分组此查询以获得所需的结果
【发布时间】:2026-02-03 07:10:01
【问题描述】:

我有一张任务表。每个任务可以有多个版本(包括草稿版本)。

  1. 每个任务都将共享一个 GUID
  2. 每个任务可以有多个版本
  3. 草稿用 version = 0 标记

我正在尝试提出一个查询,该查询将为每个任务提供一条记录。

  1. 我应该始终只获得最高版本的任务。
  2. 如果任务有草稿版本,我应该只看到那个。

我无法控制表或数据的结构。

到目前为止,我正在尝试使用 ROW_NUMBER 函数,但正在努力想出正确的解决方案。

declare @SWs TABLE
(
    Guid nvarchar(36),
    Version int,
    Title nvarchar(50),
    IsLatestVersion bit
)

INSERT INTO @SWs
select 'guid1', 1, 'StandardWork1', 1
union
select 'guid2', 1, 'StandardWork2', 0
union
select 'guid3', 1, 'StandardWork3', 1
union
select 'guid4', 1, 'StandardWork4', 1
union
select 'guid1', 0, 'StandardWork1(Draft)', 0
union
select 'guid5', 0, 'StandardWork5(Draft)', 0
union
select 'guid2', 2, 'StandardWork2.2', 1

--QUERY SHOULD RETURN ONLY ONE ROW PER GUID
--ALWAYS SHOW MAX VERSION UNLESS THERE IS DRAFT, THEN SHOW DRAFT
select 
ROW_NUMBER() OVER(PARTITION BY Guid ORDER BY Version, IsLatestVersion desc) as Row#
,Guid
,Version
,Title
,IsLatestVersion
from @SWs

但这给了我结果:

这几乎是正确的,但是带有 guid2 的任务没有正确编号。 因为它没有草稿并且也有多个版本,所以我无法让第 2 版首先出现。对此查询的任何帮助将不胜感激。

【问题讨论】:

  • Guid nvarchar(36)?有 uniqueidentifer 数据类型,'guid1' 肯定不是 guid。
  • “如果一个任务有一个草稿版本,我应该只看到那个。” 什么定义了一个草稿? Title 里面有 '(Draft') 吗?如果是这样,关于它是否是草稿的信息应该是一个单独的列。如果 something 有多个草稿会怎样?
  • 这不是真实数据。我只是把这个简单的例子放在一起来演示我遇到的结构和问题。谢谢。
  • 草稿版本有版本 0。一个任务只能有一个草稿。

标签: sql sql-server tsql sql-order-by window-functions


【解决方案1】:

我认为您希望将条件排序作为第一个条件,将 version0 的行放在首位,然后对 versionislatestversion 进行降序排序:

row_number() over(
    partition by guid 
    order by 
        case when version = 0 then 0 else 1 end, 
        version desc,
        islatestversion desc
) as row#

Demo on DB Fiddle

行# |指南 |版本 |标题 |是最新版本 ---: | :---- | ------: | :-------------------- | :-------------- 1 |指导1 | 0 |标准工作1(草稿) |错误的 2 |指导1 | 1 |标准工作1 |真的 1 |指导2 | 2 |标准工作2.2 |真的 2 |指导2 | 1 |标准工作2 |错误的 1 |引导3 | 1 |标准工作3 |真的 1 |指导4 | 1 |标准工作4 |真的 1 |指导5 | 0 | StandardWork5(草稿) |错误的

【讨论】: