如何在列中找到连续的零?

时间:2017-12-14 11:05:36

标签: sql sql-server database loops sql-server-2008

如何在列中找到连续零数(0)并在找到非零时停止。然后我需要用非零数字替换所有的零。

  1. 分组将由第1列
  2. 完成
  3. 在我们得到非零值之后,对于例如 - ABC,将其上面的所有值替换为非零值。
  4. 组中的排列将按日期的降序排列。
  5. 请告诉我如何使用非零数字更新零值。 enter image description here

5 个答案:

答案 0 :(得分:2)

试试这个

DECLARE @T TABLE
(
    Col1 VARCHAR(5),
    Col2 INT,
    Col3 DATE
)

INSERT INTO @T
values( 'ABC',0,'01-01-2017'),('ABC',0,'01-01-2017'),('ABC',0,'01-01-2014'),('ABC',3,'01-01-2013'),
('DEF',0,'01-01-2017'),('DEF',2,'01-01-2017'),('DEF',0,'01-01-2014')

;WITH CTE
AS
(
SELECT
    SeqNo = ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY Col2,Col3),
    RN = ROW_NUMBER() OVER(PARTITION BY Col1 ORDER BY Col2 DESC),
    *
    FROM @T
)
SELECT
    T1.Col1,
    NewCol2 = ISNULL(T2.Col2,T1.Col2),
    OldCol2 = T1.Col2,
    T1.Col3 
    FROM CTE T1
        LEFT JOIN CTE T2
            ON T1.Col1 = t2.Col1
                AND T1.Col2 = 0
                AND T2.RN =1

这是输出

enter image description here

程序逻辑:

  • 它根据Col2和col3为每个Col1创建一个序列。
  • 对于Col2为0的每条记录,它在同一个表上查找col1中具有相同值且Rank = 1的记录(Rank 1将是值为<> 0的记录)
  • 如果根据上述内容找到匹配项,则会显示匹配值,否则显示的值将显示在
  • 列中

答案 1 :(得分:2)

您可以尝试此解决方案,但您还需要id列(我推荐自动增量):

declare @tbl as table (
    id int
    ,column1 varchar(5)
    ,column2 int
)

insert into @tbl values (1, 'ABC', 0)
insert into @tbl values (2, 'DEF', 0)
insert into @tbl values (3, 'GHI', 0)
insert into @tbl values (4, 'JKL', 3)
insert into @tbl values (5, 'GHI', 0)
insert into @tbl values (6, 'JKL', 0)
insert into @tbl values (7, 'JKL', 4)

SELECT
    id
    ,column1
    ,CASE WHEN
        column2 = 0 THEN
            (SELECT TOP 1 column2 
            FROM @tbl <-- here you query the table again
            WHERE id > T.id <-- based on this condition you are looking onto the next row (as explained below)
                AND column2 <> 0
            ORDER BY id)
        ELSE column2
    END AS column2
FROM @tbl T <-- Here is T; is the alias of the table

<强>更新

如果您的column2 = 0子查询查看您的表并获取它找到的第一个非零值。

我告诉你有关id列的原因,你需要来自同一个表的子查询,如果条件为非零,则查询在下一行查找此条件WHERE id > T.id value将返回它,否则将查看下一行,依此类推......

因此,例如当id = 1表中的子查询搜索时,搜索id > 1以获取它找到的第一个非零值;在这种情况下,子查询将找到包含id = 4的记录并返回值3,CASE语句将执行其余操作。

答案 2 :(得分:0)

请您检查以下SQL语句 不幸的是,为了找到表格中的下一行或前一行,我们必须使用一个字段来&#34; ORDER BY&#34; 虽然您看到行按插入顺序排列,但无法保证。采用像identity或datetime列这样的列来排序和引用下一行或上一行的行是安全的

; with cte as (
select 
    z.*, s.id sid, s.Column2 sColumn2, 
    row_number() over (partition by z.id order by s.id) as rn
from zeros as z, zeros as s
where
    z.id < s.id and
    z.Column2 = 0 and
    s.Column2 > 0
)
update z
set
    Column2 = upd.sColumn2
from zeros as z
inner join (
select
    id, sColumn2 
from cte
where rn = 1
) upd
on z.id = upd.id

答案 3 :(得分:0)

如果每种类型的Column1只有一个非零值,那么在解决方案之下工作正常。

    SELECT t1.column1,coalesce(t2.column2,t1.column2) as column2,t1.column3 FROM TABLE t1 
        LEFT JOIN (SELECT column1,column2,column3 FROM TABLE WHERE column2<>0) AS t2 
        ON t1.column1=t2.column1 and t1.column3>=t2.column3
        ORDER BY  t1.column1,t1.column3 DESC

答案 4 :(得分:-1)

你需要添加像autoincremented&#39; idx&#39;这样的列。或订购数据的时间。

然后

update table set Column2=3 where idx > (select idx from table where Column2!=0 limit 0,1)