1

我有一张桌子

Val | Number 
08    | 1 
09    | 1 
10    | 1 
11    | 3 
12    | 0 
13    | 1 
14    | 1 
15    | 1 

我需要返回 Number = 1 的最后一个值(无论可能有多少),直到 Number 更改,但不需要 Number = 1 的第一个实例。基本上我需要选择返回,直到 Number 更改为 0(15、14、 13)

在 MSSQL 中是否有适当的方法来执行此操作?

4

5 回答 5

2

基于以下:

我需要返回 Number = 1 的最后一个值

基本上我需要选择回来,直到 Number 更改为 0 (15, 14, 13)

试试(小提琴演示):

select val, number 
from T 
where val > (select max(val)
              from T
              where number<>1)

编辑:解决所有可能的组合(小提琴演示 2

;with cte1 as
(
  select 1 id, max(val) maxOne
  from T
  where number=1 
),
cte2 as
(
  select 1 id, isnull(max(val),0) maxOther
  from T 
  where val < (select maxOne from cte1) and number<>1
)
select val, number
from T cross join 
   (select maxOne, maxOther
    from cte1 join cte2 on cte1.id = cte2.id
    ) X
where val>maxOther and val<=maxOne
于 2013-10-14T16:00:34.297 回答
1

我认为您可以使用窗口函数,如下所示:

with cte as (
    -- generate two row_number to enumerate distinct groups
    select
        Val, Number,
        row_number() over(partition by Number order by Val) as rn1,
        row_number() over(order by Val) as rn2
    from Table1
), cte2 as (
    -- get groups with Number = 1 and last group
    select
        Val, Number,
        rn2 - rn1 as rn1, max(rn2 - rn1) over() as rn2
    from cte
    where Number = 1
)
select Val, Number
from cte2
where rn1 = rn2

sql fiddle demo

于 2013-10-14T17:18:55.597 回答
1

演示:http ://sqlfiddle.com/#!3/e7d54/23

DDL

create table T(val int identity(8,1), number int)

insert into T values
(1),(1),(1),(3),(0),(1),(1),(1),(0),(2)

DML

; WITH last_1 AS (
  SELECT Max(val) As val
  FROM   t
  WHERE  number = 1
)
, last_non_1 AS (
  SELECT Coalesce(Max(val), -937) As val
  FROM   t
  WHERE  EXISTS (
           SELECT val
           FROM   last_1
           WHERE  last_1.val > t.val
         )
  AND    number <> 1
)
SELECT t.val
     , t.number
FROM   t
 CROSS
  JOIN last_1
 CROSS
  JOIN last_non_1
WHERE  t.val <= last_1.val
AND    t.val > last_non_1.val

我知道这有点冗长,但我故意保持这种方式来说明方法。

  1. 找到最高的val地方number=1
  2. 对于val小于步骤 1 中找到的数字的所有值,找到最大valnumber<>1
  3. 最后,找到属于我们在步骤 1 和 2 中发现的值的行。
于 2013-10-14T16:20:29.033 回答
0
select val, count (number) from
yourtable
group by val
having count(number) > 1

have 子句是这里的关键,它为您提供了所有值超过一个 1 的 val。

于 2013-10-14T15:52:36.793 回答
0

这是获取行直到某些值更改的常用方法。对于您的特定情况,请在适当的位置使用desc

创建样本表

select * into #tmp from 
(select 1 as id, 'Alpha' as value union all
select 2 as id, 'Alpha' as value union all
select 3 as id, 'Alpha' as value union all
select 4 as id, 'Beta' as value union all
select 5 as id, 'Alpha' as value union all
select 6 as id, 'Gamma' as value union all
select 7 as id, 'Alpha' as value) t

拉顶部行,直到更改:

with cte as (select * from #tmp t)
select * from
    (select cte.*, ROW_NUMBER() over (order by id) rn from cte) OriginTable
inner join 
    (
        select cte.*, ROW_NUMBER() over (order by id) rn from cte
        where cte.value = (select top 1 cte.value from cte order by cte.id)
    ) OnlyFirstValueRecords
on OriginTable.rn = OnlyFirstValueRecords.rn and OriginTable.id = OnlyFirstValueRecords.id

在左侧,我们放了一张原始桌子。在右侧,我们只放置其值等于第一行中的值的行。
两个表中的记录将相同,直到目标值更改。在第 3 行之后,行号将因为偏移而获得不同的关联 ID,并且永远不会与原始表连接:

LEFT           RIGHT
ID Value RN    ID Value RN
1  Alpha  1  | 1  Alpha 1
2  Alpha  2  | 2  Alpha 2
3  Alpha  3  | 3  Alpha 3
----------------------- result set ends here
4  Beta   4  | 5  Alpha 4  
5  Alpha  5  | 7  Alpha 5
6  Gamma  6  |
7  Alpha  7  |

ID 必须是唯一的。在两个 ROW_NUMBER() 函数中,此 ID 的排序必须相同。

于 2021-10-28T19:57:38.217 回答