SQL Server: может кто-нибудь упростить эту логику - PullRequest
0 голосов
/ 24 февраля 2012

Мой запрос, как показано ниже

declare @row_id int = 2
declare @last_row_id int  =(select MAX(Row_ID) from dbo.Source)

create table #source  (
    Row_ID float null,
      [Document] [nvarchar](255) NULL,    
      [ITEMCode] [nvarchar](255) NULL,    
      [Text] [nvarchar](255) NULL)

while(@row_id<=(@last_row_id))
begin

declare @Document nvarchar(255)
declare @itemcode nvarchar(255)

select @itemcode=ITEMCode,@Document=Document from dbo.Source where Row_ID=@row_id


if ((@itemcode='' or @itemcode is null ) )
select @itemcode=ITEMCode,@Document=Document from #source where Row_ID=@row_id-1

insert into #source
select Row_ID,@Document,@itemcode,[Text]
from dbo.Source where Row_ID=@row_id

print @row_id

set @row_id= @row_id+1

end

select * from #source
drop table #source

В настоящее время в моей таблице 347000 строк. Это занимает больше часа, чтобы получить окончательный вывод.Как этот запрос может быть сделан быстрее.Кто-нибудь может помочь?

Требование:

Источник:

  Row_ID    Document    ITEMCode     Text                   
    2      10223         20235       aaaa
    3                                    bbbb
    4                                    cccc
    5      10278         202475      xxxx
    6                                    yyyy
    7                                    yyy

Вывод должен быть:

 Row_ID  Document  ITEMCode Text    
   2       10223     20235  aaaa
   3       10223     20235  bbbb
   4       10223     20235  cccc
   5       10278    202475  xxxx
   6       10278    202475  yyyy
   7       10278    202475  yyy

Ответы [ 2 ]

1 голос
/ 24 февраля 2012

Вы можете использовать рекурсив CTE :

WITH
  Source (Row_ID, Document, ITEMCode, Text) AS (
    SELECT 2, '10223', '20235' , 'aaaa' UNION ALL
    SELECT 3, ''     , ''      , 'bbbb' UNION ALL
    SELECT 4, ''     , ''      , 'cccc' UNION ALL
    SELECT 5, '10278', '202475', 'xxxx' UNION ALL
    SELECT 6, '10278', '202475', 'yyyy' UNION ALL
    SELECT 7, '10278', '202475', 'yyy'
  ),
  ranked AS (
    SELECT
      *,
      rnk = ROW_NUMBER() OVER (ORDER BY Row_ID)
    FROM Source
  ),
  filled AS (
    SELECT
      Row_ID,
      Document,
      ITEMCode,
      Text,
      rnk
    FROM ranked
    WHERE rnk = 1
    UNION ALL
    SELECT
      r.Row_ID,
      Document = ISNULL(NULLIF(r.Document, ''), f.Document),
      ITEMCode = ISNULL(NULLIF(r.ITEMCode, ''), f.ITEMCode),
      r.Text,
      r.rnk
    FROM ranked r
      INNER JOIN filled f ON r.rnk = f.rnk + 1
  )
SELECT
  Row_ID,
  Document,
  ITEMCode,
  Text
FROM filled

Выход:

Row_ID      Document ITEMCode Text
----------- -------- -------- ----
2           10223    20235    aaaa
3           10223    20235    bbbb
4           10223    20235    cccc
5           10278    202475   xxxx
6           10278    202475   yyyy
7           10278    202475   yyy

Если Document и ITEMCode на самом деле являются целыми числами, а не строками, вышеприведенный скрипт будет работать, но в целом было бы лучше изменить эти две строки:

Document = ISNULL(NULLIF(r.Document, ''), f.Document),
ITEMCode = ISNULL(NULLIF(r.ITEMCode, ''), f.ITEMCode),

как это:

Document = ISNULL(NULLIF(r.Document, <b>0</b>), f.Document),
ITEMCode = ISNULL(NULLIF(r.ITEMCode, <b>0</b>), f.ITEMCode),
0 голосов
/ 28 февраля 2012

Несмотря на то, что указанные выше запросы могут работать, я написал макрос в Excel, к которому мы стремимся быстро и получил результат менее чем за 5 минут

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...