Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Замяна на букви с нула във всеки даден низ в SQL

Това изисква редица донякъде усъвършенствани техники, комбинирани за това. Първият проблем е, че имате разделени данни. Това нарушава 1NF, когато натъпчете множество стойности в една клетка. Второто парче от пъзела е как да PIVOT тези данни в динамичен брой колони. Повечето хора около SO предпочитат да използват динамичен PIVOT. Вместо това предпочитам да използвам динамичен напречен раздел. Намирам синтаксиса за по-малко тъп и дори е малко по-ефективен от динамичен напречен раздел.

Можете да прочетете за сплитера, който обикновено използвам тук. http://www.sqlservercentral.com/articles/Tally+Table/72993/ Основното предимство, което този сплитер предлага, което повечето други не предлагат, е, че връща номера на реда на елемента в списъка със стойности. Това е невероятно полезно за този тип ситуации. Ако наистина искате да се потопите в света на сплитерите, ето няколко други отлични опции. http://sqlperformance.com/2012/07/t-sql -queries/split-strings

Можете да прочетете повече за динамичните кръстосани раздели тук. http://www.sqlservercentral.com/articles/Crosstab/65048/

Наистина не разбирам какво общо има таблицата #STATICFILTER с това, така че просто я игнорирах.

Уверете се, че разбирате този код, преди да го приложите. Посочените статии разглеждат много подробно тези техники.

if OBJECT_ID('tempdb..#MathTemp1') is not null
    drop table #MathTemp1

CREATE TABLE #MathTemp1
(
    IDNUM INTEGER IDENTITY(1,1),
    YEARMONTH VARCHAR(256),
    OutputFormula VARCHAR(256),
    Timedimensiondate Date
)

INSERT INTO #MathTemp1 (YEARMONTH,OUTPUTFORMULA,Timedimensiondate)
VALUES ('CV(N2)  1989: 1','2641.000 + Import - Consumption customs value(1540) + Import - Consumption customs value(1541)','1989-01-01')
,('CV(N2)  1989: 10','54407.000 + Import - Consumption customs value(1540) + 63906.000','1989-10-01')
,('CV(N2)  1990: 11','Import - Consumption customs value(2266) + Import - Consumption customs value(1540) + 53088.000','1990-11-01')
,('CV(N2)  1994: 5','32852.000 + Import - Consumption customs value(1540) + Import - Consumption customs value(1541)','1994-05-01')

declare @StaticPortion nvarchar(2000) = 
    'with OrderedResults as
    (   
        select mt.IDNUM
            , mt.OutputFormula
            , mt.Timedimensiondate
            , mt.YEARMONTH
            , x.ItemNumber
            , LTRIM(RTRIM(x.Item)) as Item
        from #MathTemp1 mt
        cross apply dbo.DelimitedSplit8K(mt.OutputFormula, ''+'') x
    )
    Select IDNUM';

declare @DynamicPortion nvarchar(max) = '';
declare @FinalStaticPortion nvarchar(2000) = ' from OrderedResults Group by IDNUM order by IDNUM';  

with E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS 
(
    SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)

select @DynamicPortion = @DynamicPortion + 
    ', MAX(Case when ItemNumber = ' + CAST(N as varchar(6)) + 'then case when ISNUMERIC(Item) = 1 then convert(numeric(9,3), ltrim(rtrim(Item))) else 0 end end) as Value' + CAST(N as varchar(6)) + CHAR(10)
from cteTally t
where t.N <= 
(
    select MAX(LEN(OutputFormula) - LEN(replace(OutputFormula, '+', ''))) + 1
    from #MathTemp1
)


declare @SqlToExecute nvarchar(max) = @StaticPortion + @DynamicPortion + @FinalStaticPortion;

--select @SqlToExecute
exec sp_executesql @SqlToExecute



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Използване на CASE изрази в SQL Server

  2. Показатели за производителност на SQL сървъра, за да останете пред играта

  3. Ограничение на условието WHERE col IN (...).

  4. Не мога да накарам sql server compact 3.5 / 4 да работи с ASP .NET MVC 2

  5. Как да проверите дали изчислената колона е „постоянна“ в SQL Server