I have a dilemma, I'm able to convert the following Sample data:
declare @table table
(
iTermID int
, cTermDesc1 varchar(30)
, cTermDesc2 varchar(30)
, cTermDesc3 varchar(30)
, cTermDesc4 varchar(30)
, cTermDesc5 varchar(30)
, cTermDesc6 varchar(30)
, cTermDesc7 varchar(30)
)
insert into @table
(
iTermID
, cTermDesc1
, cTermDesc2
, cTermDesc3
, cTermDesc4
, cTermDesc5
, cTermDesc6
, cTermDesc7
)
values
(1,'Current','30 Days','60 Days','90 Days','120 Days','150 Days','180 Days')
, (3,'Current','30 Days','60 Days','90 Days','120 Days','150 Days','180 Days')
, (4,'Current','7 Days','14 Days','21 Days','28 Days','35 Days','42 Days')
, (5,'Current','14 Days','28 Days','42 Days','56 Days','70 Days','84 Days');
with this script:
with cte as (
select
cTermDesc1+','+cTermDesc2+','+cTermDesc3+','+cTermDesc4+','+cTermDesc5+','+cTermDesc6+','+cTermDesc7 term
from @table
)
, data as (
select distinct
Value
from cte
outer apply string_split(term,',')
)
, retur as (
select
Value
,
case Value
when 'Current' then 1
when '7 Days' then 2
when '14 Days' then 3
when '21 Days' then 4
when '28 Days' then 5
when '35 Days' then 6
when '42 Days' then 7
when '56 Days' then 8
when '70 Days' then 9
when '84 Days' then 10
when '30 Days' then 11
when '60 Days' then 12
when '90 Days' then 13
when '120 Days' then 14
when '150 Days' then 15
when '180 Days' then 16
else 17 end sort
from data
)
select
string_agg(quotename(Value),',') within group (order by sort desc)
from retur
to look like this (expected results) (fiddle):
[180 Days],[150 Days],[120 Days],[90 Days],[60 Days],[30 Days],[84 Days],[70 Days],[56 Days],[42 Days],[35 Days],[28 Days],[21 Days],[14 Days],[7 Days],[Current]
I require to get the same results as my expected results above, but without using a CASE
.
I tried altering my CTE
to this:
with cte as (
select
'1-'+cTermDesc1+','+'2-'+cTermDesc2+','+'3-'+cTermDesc3+','+'4-'+cTermDesc4+','+'5-'+cTermDesc5+','+'6-'+cTermDesc6+','+'7-'+cTermDesc7 term
from @table
)
, data as (
select distinct
Value
from cte
outer apply string_split(term,',')
)
, retur as (
select
substring(Value,charindex('-',Value,1)+1,20) Value
, left(Value,1) sort
from data
)
select
string_agg(quotename(Value),',') within group (order by sort desc)
from retur
But now I don't get the same order as my expected results above.
Results:
[180 Days],[42 Days],[84 Days],[150 Days],[35 Days],[70 Days],[120 Days],[28 Days],[56 Days],[21 Days],[42 Days],[90 Days],[14 Days],[28 Days],[60 Days],[14 Days],[30 Days],[7 Days],[Current]
Is there maybe an easier way I can achieve this?
PLEASE NOTE THAT I ONLY NEED ONE "CURRENT" RETURNED
EDIT
Here is my sample data with the Code included:
declare @table table
(
iTermID int
, Code varchar(30)
, cTermDesc1 varchar(30)
, cTermDesc2 varchar(30)
, cTermDesc3 varchar(30)
, cTermDesc4 varchar(30)
, cTermDesc5 varchar(30)
, cTermDesc6 varchar(30)
, cTermDesc7 varchar(30)
)
insert into @table
(
iTermID
, Code
, cTermDesc1
, cTermDesc2
, cTermDesc3
, cTermDesc4
, cTermDesc5
, cTermDesc6
, cTermDesc7
)
values
(1,'MNTH-INV','Current','30 Days','60 Days','90 Days','120 Days','150 Days','180 Days')
, (3,'MNTH-STM','Current','30 Days','60 Days','90 Days','120 Days','150 Days','180 Days')
, (4,'7 Days','Current','7 Days','14 Days','21 Days','28 Days','35 Days','42 Days')
, (5,'14 Days','Current','14 Days','28 Days','42 Days','56 Days','70 Days','84 Days')
Here's a generic version that will always put the values from MNTH-INV
and MNTH-STM
in sequence before the values for 7 days
and 14 days
. It gives the correct sequence of values for the inputs in the question.
It's hard to be sure whether this is correct in all circumstances, since the rules for defining the order aren't explicitly given in the question/comments.
(All of the logic here has been written without CASE
since when I was working on it I hadn't seen the comment that explains why the OP wants to avoid CASE
)
;WITH grpCTE
AS
(
SELECT v.grp,
t.cTermDesc1,t.cTermDesc2,t.cTermDesc3,t.cTermDesc4,t.cTermDesc5,t.cTermDesc6,t.cTermDesc7
FROM @table AS t
JOIN (VALUES (1,1),(3,1), (4,2), (5,2)) AS v(iTermID, grp)
ON v.iTermID = t.iTermID
)
,valuesCTE
AS
(
SELECT grp, cTermDesc1 AS dayCount FROM grpCTE
UNION
SELECT grp, cTermDesc2 AS dayCount FROM grpCTE
UNION
SELECT grp, cTermDesc3 AS dayCount FROM grpCTE
UNION
SELECT grp, cTermDesc4 AS dayCount FROM grpCTE
UNION
SELECT grp, cTermDesc5 AS dayCount FROM grpCTE
UNION
SELECT grp, cTermDesc6 AS dayCount FROM grpCTE
UNION
SELECT grp, cTermDesc7 AS dayCount FROM grpCTE
)
,aggCTE
AS
(
SELECT STRING_AGG(QUOTENAME(dayCount),',') WITHIN GROUP (ORDER BY grp, TRY_CAST(LEFT(dayCount,3) AS INT) desc) AS retur
FROM valuesCTE
WHERE TRY_CAST(LEFT(dayCount,3) AS INT) IS NOT NULL
)
SELECT CONCAT(retur, ',[' + v.dayCount + ']') AS retur
FROM aggCTE AS a
OUTER
APPLY (SELECT TOP(1) dayCount FROM valuesCTE WHERE dayCount = 'Current') AS v