Thursday, August 1, 2019

SQL - Use of PARSENAME() function

Sometimes when we have pivoted value in excel or csv with title as 'Column 1','Column 2',...'Column n'. But in the meantime, those columns means the dates like 1980-01-01, 1980-02-01. After unpivot the data into sql , the data will be like this:
API               date_string Product
053-29070 Column 112 Oil
053-29070 Column 113 Oil
053-29070 Column 118 Oil
053-29070 Column 172 Oil
053-29070 Column 173 Oil
053-29070 Column 177 Oil
053-29070 Column 178 Oil
053-29070 Column 19 Oil
Then how do we know the corresponding year and month?

So here is the trick. Function PARSENAME() can get the specific part of a string delimited by a delimiter. so
for SELECT PARSENAME(12.3,1), you will get 3,
for SELECT PARSENAME(13%12,1), you will get 1

so by using this function together with remainder function, we can get the month of the data.
by using some tricks with number/12, we can get the year of the data.

date_string date_int month_indicator year_indicator date_int_plus
Column 1 1 1 0 2
Column 2 2 2 0 3
Column 3 3 3 0 4
Column 4 4 4 0 5
Column 5 5 5 0 6
Column 6 6 6 0 7
Column 7 7 7 0 8
Column 8 8 8 0 9
Column 9 9 9 0 10
Column 10 10 10 0 11
Column 11 11 11 0 12
Column 12 12 0 1 13
Column 13 13 1 1 14
Column 14 14 2 1 15
Column 15 15 3 1 16
Column 16 16 4 1 17
Column 17 17 5 1 18
Column 18 18 6 1 19
Column 19 19 7 1 20
Column 20 20 8 1 21
Column 21 21 9 1 22
Column 22 22 10 1 23
Column 23 23 11 1 24

--------------------------update production_month---------------------------------------
so we can   set  production_month = 
     case      when PARSENAME(cast(replace(date_string,'Column ','') as int)%12,1) = 1 then 1
                  when PARSENAME(cast(replace(date_string,'Column ','') as int)%12,1) = 2 then 2
  when PARSENAME(cast(replace(date_string,'Column ','') as int)%12,1) = 3 then 3
  when PARSENAME(cast(replace(date_string,'Column ','') as int)%12,1) = 4 then 4
  when PARSENAME(cast(replace(date_string,'Column ','') as int)%12,1) = 5 then 5
  when PARSENAME(cast(replace(date_string,'Column ','') as int)%12,1) = 6 then 6
  when PARSENAME(cast(replace(date_string,'Column ','') as int)%12,1) = 7 then 7
  when PARSENAME(cast(replace(date_string,'Column ','') as int)%12,1) = 8 then 8
  when PARSENAME(cast(replace(date_string,'Column ','') as int)%12,1) = 9 then 9
  when PARSENAME(cast(replace(date_string,'Column ','') as int)%12,1) = 10 then 10
  when PARSENAME(cast(replace(date_string,'Column ','') as int)%12,1) = 11 then 11
  when PARSENAME(cast(replace(date_string,'Column ','') as int)%12,1) = 0 then 12
  else null 
  end
--------------------------update production_year---------------------------------------
IF OBJECT_ID('tempdb..#tbl_prod') IS NOT NULL DROP TABLE #tbl_prod
select distinct cast(PARSENAME(cast(replace(date_string,'Column ','') as int)/12,1) as int) as year_indicator, cast(replace(date_string,'Column ','') as int) +1 as date_int_plus
into #tbl_prod
from XXXX with (nolock)

DECLARE @counter int = 0; 
WHILE @counter <= (select max(cast(replace(date_string,'Column ','') as int)) from XXXX)
BEGIN
update a
set production_year = 1980 + @counter
from XXXX a ,#tbl_prod b
where b.year_indicator = @counter and cast(replace(a.date_string,'Column ','') as int) =               
                  b.date_int_plus and a.api <> '' and a.volume <> 0 and a.volume is not null ;
SET @counter = @counter + 1;
END

--only column 1 is not assigned a year
update XXXX
set production_year = 1980
where date_string = 'Column 1' and api <> '' and volume is not null and volume <> 0;

Or just the easiest way. Use SELECT DATEADD(MONTH,+1,getdate()) to get the date.

No comments:

Post a Comment