Creating a string of combined values from a SQL Server table - sql

I built a SQL query which returns the following results:
ID Number ID IndexColumn String_To_Use Checking_ID
0000 1 0000 1 -2
1000 2 1000 2 -2
1020 3 1020 3 -2
1130 4 1130 4 -2
1198 5 NULL 9999 NULL NULL
1199 6 1199 5 -2
1210 7 1210 6 -2
1240 8 NULL 9999 NULL NULL
1250 9 NULL 9999 NULL NULL
1260 10 1260 7 7
1261 11 NULL 9999 NULL NULL
1280 12 NULL 9999 NULL NULL
1296 13 NULL 9999 NULL NULL
1298 14 NULL 9999 NULL NULL
1299 15 1299 8 8
1501 16 NULL 9999 NULL NULL
I need to populate the column "String_To_Use" with "ID" values in such a way that If "Checking_ID" column has values -2 more than once repeating (it means user chose IDs in a range), these repeating values would be displayed as "0000-1130"; if values -2 is not being repeated, then for example "1260".
Based on this logic, the above table will contain the following values in the String_To_Use column:
ID Number ID IndexColumn String_To_Use Checking_ID
0000 1 0000 1 0000-1130 -2
1000 2 1000 2 0000-1130 -2
1020 3 1020 3 0000-1130 -2
1130 4 1130 4 0000-1130 -2
1198 5 NULL 9999 NULL NULL
1199 6 1199 5 0000-1210 -2
1210 7 1210 6 0000-1210 -2
1240 8 NULL 9999 NULL NULL
1250 9 NULL 9999 NULL NULL
1260 10 1260 7 1260 7
1261 11 NULL 9999 NULL NULL
1280 12 NULL 9999 NULL NULL
1296 13 NULL 9999 NULL NULL
1298 14 NULL 9999 NULL NULL
1299 15 1299 8 1299 8
1501 16 NULL 9999 NULL NULL
thank you!!

You need to define groups of "adjacency". In this case, you can simply do a cumulative sum of the number of times that checking_id is not -2.
After that, the rest is window functions and string manipulation:
select t.*,
(case when checking_id <> -2
then min(id) over (partition by grp) + '-' + max(id) over (partition by grp)
else id
end) as string_to_use
from (select t.*,
sum(case when checking_id <> -2 then 1 else 0 end) over (order by id) as grp
from t
) t;
This version assumes that id is a string. If it is a number, the code is easily adapted by cluttering it with cast() or convert().

select t.*,
(case when Checking_id = -2
then min(id) over (partition by grp) + '-' + max(id) over (partition by grp)
else id
end) as string_to_use
from (select t.*
,sum(case when Checking_id = -2 then 1 else 0 end) over (partition by id) as grp
from t
) t order by id;
ID Number ID IndexColumn String_To_Use Checking_id grp string_to_use
0000 1 0000 1 -2 1 0000 -1210
1000 2 1000 2 -2 1 0000 -1210
1020 3 1020 3 -2 1 0000 -1210
1130 4 1130 4 -2 1 0000 -1210
1198 5 NULL 9999 NULL NULL 0 NULL
1199 6 1199 5 -2 1 0000 -1210
1210 7 1210 6 -2 1 0000 -1210
1240 8 NULL 9999 NULL NULL 0 NULL
1250 9 NULL 9999 NULL NULL 0 NULL
1260 10 1260 7 7 0 1260
1261 11 NULL 9999 NULL NULL 0 NULL
1280 12 NULL 9999 NULL NULL 0 NULL
1296 13 NULL 9999 NULL NULL 0 NULL
1298 14 NULL 9999 NULL NULL 0 NULL
1299 15 1299 8 8 0 1299
1501 16 NULL 9999 NULL NULL 0 NULL

Related

how to do sum with multiple joins in PostgreSQL?

I know that my question would be duplicated but I really don't know how to created sql which return results of sum with multiple join.
Tables I have
result_summary
num_bin id_summary count_bin
3 172 0
4 172 0
5 172 0
6 172 0
7 172 0
8 172 0
1 174 1
2 174 0
3 174 0
4 174 0
5 174 0
6 174 0
7 174 0
8 174 0
1 175 0
summary_assembly
num_lot id_machine sabun date_work date_write id_product shift count_total count_fail count_good id_summary id_operation
adfe 1 21312 2020-11-25 2020-11-25 1 A 10 2 8 170 2000
adfe 1 21312 2020-11-25 2020-11-25 1 A 1000 1 999 171 2000
adfe 1 21312 2020-11-25 2020-11-25 2 A 100 1 99 172 2000
333 1 21312 2020-12-06 2020-12-06 1 A 10 2 8 500 2000
333 1 21312 2020-11-26 2020-11-26 1 A 10000 1 9999 174 2000
333 1 21312 2020-11-26. 2020-11-26 1 A 100 0 100 175 2000
333 1 21312 2020-12-06 2020-12-06 1 A 10 2 8 503 2000
333 1 21312 2020-12-07 2020-12-07 1 A 10 2 8 651 2000
333 1 21312 2020-12-02 2020-12-02 1 A 10 2 8 178 2000
employees
sabun name_emp
3532 Kim
12345 JS
4444 Gilsoo
21312 Wayn Hahn
123 Lee too
333 JD
info_product
id_product name_product
1 typeA
2 typeB
machine
id_machine id_operation name_machine
1 2000 name1
2 2000 name2
3 2000 name3
4 3000 name1
5 3000 name2
6 3000 name3
7 4000 name1
8 4000 name2
query
select S.id_summary, I.name_product, M.name_machine,
E.name_emp, S.sabun, S.date_work,
S.shift, S.num_lot, S.count_total,
S.count_good, S.count_fail,
sum(case num_bin when '1' then count_bin else 0 end) as bin1,
sum(case num_bin when '2' then count_bin else 0 end) as bin2,
sum(case num_bin when '3' then count_bin else 0 end) as bin3,
sum(case num_bin when '4' then count_bin else 0 end) as bin4,
sum(case num_bin when '5' then count_bin else 0 end) as bin5,
sum(case num_bin when '6' then count_bin else 0 end) as bin6,
sum(case num_bin when '7' then count_bin else 0 end) as bin7,
sum(case num_bin when '8' then count_bin else 0 end) as bin8
from result_assembly as R
join summary_assembly as S on R.id_summary = S.id_summary
join employees as E on S.sabun = E.sabun
join info_product as I on S.id_product = I.id_product
join machine as M on S.id_machine = M.id_machine
where I.id_product = '1'
and E.sabun='21312'
and S.shift = 'A'
and S.date_work between '2020-11-10' and '2020-12-20'
group by S.id_summary, E.name_emp, S.num_lot,
I.name_product,M.name_machine
order by S.id_summary;
result
id_summary name_product name_machine name_emp sabun date_work shift num_lot count_total count_good count_fail bin1 bin2 bin3 bin4 bin5 bin6 bin7 bin8
170 TypeA name1 Kim 21312 2020-11-25 A adfe 10 8 2 1 1 0 0 0 0 0 0
171 TypeA name1 Kim 21312 2020-11-25 A adfe 1000 999 1 1 1 0 0 0 0 0 0
174 TypeA name1 Kim 21312 2020-11-26 A 333 10000 9999 1 1 1 0 0 0 0 0 0
175 TypeA name1 Kim 21312 2020-11-26 A 333 100 100 0 0 0 0 0 0 0 0 0
178 TypeA name1 Kim 21312 2020-12-02 A 333 10 8 2 1 1 0 0 0 0 0 0
179 TypeA name1 Kim 21312 2020-12-02 A 333 10 8 2 1 1 0 0 0 0 0 0
180 TypeA name1 Kim 21312 2020-12-02 A 333 10 8 2 1 1 0 0 0 0 0 0
181 TypeA name1 Kim 21312 2020-12-02 A 333 10 8 2 1 1 0 0 0 0 0 0
182 TypeA name2 Kim 21312 2020-12-02 A 333 10 8 2 1 1 0 0 0 0 0 0
186 TypeA name2 Kim 21312 2020-12-06 A 333 10 8 2 1 1 0 0 0 0 0 0
193 TypeA name2 Kim 21312 2020-12-06 A 333 10 8 2 0 0 0 0 0 0 0 0
194 TypeA name2 Kim 21312 2020-12-06 A 333 10 8 2 0 0 0 0 0 0 0 0
195 TypeA name2 Kim 21312 2020-12-06 A 333 10 8 2 0 0 0 0 0 0 0 0
196 TypeA name2 JS 21312 2020-12-06 A 333 10 8 2 0 0 0 0 0 0 0 0
197 TypeA name2 JS 21312 2020-12-06 A 333 10 8 2 0 0 0 0 0 0 0 0
198 TypeA name2 JS 21312 2020-12-06 A 333 10 8 2 0 0 0 0 0 0 0 0
199 TypeA name2 JS 21312 2020-12-06 A 333 10 8 2 0 0 0 0 0 0 0 0
200 TypeA name2 JS 21312 2020-12-06 A 333 10 8 2 0 0 0 0 0 0 0 0
expected output(when sum by num_lot)
num_lot count_total count_good count_fail bin1 bin2 bin3 bin4 bin5 bin6 bin7 bin8
adfe 323 300 23 22 1 0 0 0 0 0 0
333 4312 4300 12 10 2 0 0 0 0 0 0
All of them were modified from original one because they were non-English, so there would be typo.
Here now I need to sum by num_lot, name_product or sabun.
id_summary is unique.
Thanks
As expected in the comments: It seems like you simple need a subquery which groups your table by the column num_lot
SELECT
num_lot,
SUM(count_total),
SUM(count_good)
-- some more SUM()
FROM (
--<your query>
) s
GROUP BY num_lot
It was asked in the comments what the s stands for: A subquery needs an alias, an identifier. Because I didn't want to think about a better name, I just called the subselect s. It is the shortcut for AS s
It sounds like you want to use crosstab() -- https://www.postgresql.org/docs/current/tablefunc.html

Implement the Scalar Function inside a CTE

i have a View(The View contains a CTE inside it as shown below) where in I am calling one Scalar Function and in the same scalar function the view is called. This whole process making the performance slower. Can i implement the function's functionality in the same View.
Please help
WITH tree AS
(
SELECT c1.structureid,c1.assessmentid, c1.sequence,c1.Required,c1.Objective, c1.parentid, c1.Text, [level] = 1, path = cast( c1.structureid as varchar(100))
FROM [ast].[Structure] c1
WHERE c1.parentid IS NULL
UNION ALL
SELECT c2.structureid, c2.assessmentid, c2.sequence,c2.Required,c2.Objective, c2.parentid, c2.Text, [level] = tree.[level] + 1,
Path = Cast(tree.path+'/'+right('000000000' + cast(c2.structureid as varchar(10)),10) as varchar(100))
FROM [ast].[Structure] c2 INNER JOIN tree ON tree.structureid = c2.parentid
)
SELECT tree.level,tree.sequence,
tree.path, parentid, tree.assessmentid, tree.Required,tree.Objective, (SELECT [dbo].Tree_full_index(tree.structureid))+' '+ tree.Text AS description ,C.* ,
wasScored = (case when C.choiceid is null then 0 else 1 end ),
wasDerived = (case when C.choiceid is null and C.Score is not null then 1 else 0 end )
FROM tree inner join [ast].[Value] as C on tree.structureid = C.structureid
Scalar Function
ALTER FUNCTION [dbo].[Tree_full_index]
(
#tree_node_id int
)
RETURNS varchar(20)
AS
BEGIN
declare #result varchar(20)
set #result =''
declare #node_seq_index varchar(5)
DECLARE #parentID int
select #node_seq_index=isnull(sequence,''),#parentID=isnull(parentid,0) from vwAssesment where structureid=#tree_node_id
set #result=#node_seq_index
WHILE #parentID > 0
BEGIN
SELECT #tree_node_id = #parentID
select #node_seq_index=isnull(sequence,''),#parentID=parentid from vwAssesment where structureid=#tree_node_id
set #result=#node_seq_index+'.0'+#result
END
RETURN #result
END
Structure Table
StructureId AssessmentId ParentId Required Sequence Text Objective
633 132 NULL 1 1 Customer Satisfaction understand our top Customers and our supplier ranking with them.
634 132 633 1 1 Top Customers NULL
635 132 634 1 1 Display top Customers on Lead Board NULL
636 132 634 1 2 Display Customer Supplier Ranking for Facility - NA NULL
637 132 634 1 3 Display Work Plan that provides path to Preferred Supplier status NULL
638 132 633 1 2 Real Time Response Process NULL
639 132 638 0 1 Real-time response system in place when abnormalities occur with documented Counter Measures NULL
640 132 NULL 1 2 Continuous Improvement ensure driving foundation for Continuous Improvement
641 132 640 1 1 Gemba NULL
642 132 641 1 1 Routine and scheduled NULL
643 132 641 1 2 Incorporated into appropriate different levels of organization NULL
644 132 640 1 2 TPM NULL
645 132 644 1 1 Perform initial Cleaning & Inspection (Level 1) NULL
646 132 645 1 1 Learn how to identify equipment problems NULL
The result Should have the column with actual index of the Node as shown
level sequence parentid assessmentid Required Objective description ValueId InstanceId StructureId ChoiceId Score wasScored wasDerived
1 1 NULL 132 1 understand our top Customers and our supplier ranking with them. Ensure In-Station Quality and continuous improvement. 1 Customer Satisfaction 666 207 633 NULL 2 0 1
2 1 633 132 1 NULL 1.01 Top Customers 667 207 634 NULL 4 0 1
3 1 634 132 1 NULL 1.01.01 Display top Customers on Lead Board 668 207 635 40 4 1 0
3 2 634 132 1 NULL 1.01.02 Display Customer Supplier Ranking for Facility - NA 669 207 636 40 4 1 0
3 3 634 132 1 NULL 1.01.03 Display Work Plan that provides path to Preferred Supplier status 670 207 637 40 4 1 0
2 2 633 132 1 NULL 1.02 Real Time Response Process 671 207 638 NULL NULL 0 0
3 1 638 132 0 NULL 1.02.01 Real-time response system in place when abnormalities occur with documented Counter Measures 672 207 639 NULL NULL 0 0
1 2 NULL 132 1 ensure driving foundation for Continuous Improvement culture to be successful and achieve meaningful results 2 Continuous Improvement 673 207 640 NULL 3.5 0 1
2 1 640 132 1 NULL 2.01 Gemba 674 207 641 20 2 1 0
3 1 641 132 1 NULL 2.01.01 Routine and scheduled 675 207 642 NULL NULL 0 0
3 2 641 132 1 NULL 2.01.02 Incorporated into appropriate different levels of organization (Facility Manager, Staff, site Director) 676 207 643 NULL NULL 0 0
2 2 640 132 1 NULL 2.02 TPM 677 207 644 NULL 5 0 1
3 1 644 132 1 NULL 2.02.01 Perform initial Cleaning & Inspection (Level 1) 678 207 645 50 5 1 0
4 1 645 132 1 NULL 2.02.01.01 Learn how to identify equipment problems 679 207 646 NULL NULL 0 0
You can implement the function in the view or in a CTE before the tree cte, as below:-
;with prev as (
select *,1 [depth],cast(isnull([sequence],'') as varchar(max)) [Tree_full_index] From vwAssesment where parentid is null
union all
select v.*,prev.depth+1 [depth],+[Tree_full_index]+'.0'+isnull(v.[sequence],'') from prev
inner join vwAssesment v on v.parentid=prev.structureid
),Tree as (.......
I tested the prev cte, it will return the Tree_full_index as part of it with all columns of vwAssesment , so change your query to use prev instead of vwAssesment, or update vwAssesment or create a new view to have the Tree_full_index and use it
For the belowsample data:-
Declare #vwAssesment Table(
structureid int,
parentid int,
[sequence] varchar(5)
)
insert into #vwAssesment values(1,null,'1')
insert into #vwAssesment values(2,null,'2')
insert into #vwAssesment values(3,null,'3')
insert into #vwAssesment values(4,1, '1')
insert into #vwAssesment values(5,1, '2')
insert into #vwAssesment values(6,1, '3')
insert into #vwAssesment values(7,2, '2')
insert into #vwAssesment values(8,2, '3')
insert into #vwAssesment values(9,8, '2')
insert into #vwAssesment values(10,8,'3')
The result is:-
structureid parentid sequence depth Tree_full_index
1 NULL 1 1 1
2 NULL 2 1 2
3 NULL 3 1 3
4 1 1 2 1.01
5 1 2 2 1.02
6 1 3 2 1.03
7 2 2 2 2.02
8 2 3 2 2.03
9 8 2 3 2.03.02
10 8 3 3 2.03.03

T SQL CTE Previous Row Calculation

I'm using SQL Server 2016.
I have the below table:
SKU Shop Week ShopPrioirty Replen Open_Stk Open_Stk Calc
111 100 1 1 0 17 NULL
111 200 1 2 2 NULL NULL
111 300 1 3 0 NULL NULL
111 400 1 4 0 NULL NULL
222 100 2 1 5 17 NULL
222 200 2 2 5 NULL NULL
222 300 2 3 5 NULL NULL
222 400 2 4 5 NULL NULL
This is the desired result:
SKU Shop Week ShopPrioirty Replen Open_Stk Open_Stk Calc
111 100 1 1 0 17 17
111 200 1 2 2 NULL 17
111 300 1 3 0 NULL 15
111 400 1 4 0 NULL 15
222 100 2 1 20 17 17
222 200 2 2 15 NULL 12
222 300 2 3 12 NULL 7
222 400 2 4 10 NULL 2
I need to update the 'Open_Stk Calc' based on the previous row:
'Open_Stk Calc' - IIF('Replen'<=IIF('Open_Stk'>=0,'Open_Stk',0),'Replen',0)
I am using a CTE to update a row based on a calculation of the previous rows. This is my SQL:
;WITH CTE AS
(
SELECT
SKU,
[Shop],
[Week],
[Store_Priority],
[Replen],
[Open_Stk],
[Open_Stk Calc],
FIRST_VALUE([Open_Stk]) OVER ( PARTITION BY [SKU] ,[Week] ORDER BY [Store_Priority] ROWS UNBOUNDED PRECEDING)
-
ISNULL(SUM(IIF([Replen] <= IIF([Open_Stk]>=0,[Open_Stk],0),[Replen],0))
OVER (PARTITION BY [SKU] ,[Week] ORDER BY [Store_Priority] ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), 0) AS CurrentStock
FROM [tblTEST])
UPDATE CTE
SET [Open_Stk Calc] = CurrentStock
However, this produces the following result:
SKU Shop Week ShopPrioirty Replen Open_Stk Open_Stk Calc
111 100 1 1 0 17 17
111 200 1 2 2 NULL 17
111 300 1 3 0 NULL 17
111 400 1 4 0 NULL 17
And not the desired result - where have I gone wrong?
As one can see in the MS documentation, the OVER clauses supports specific kind of functions:
Ranking functions
Aggregate functions
Analytic functions
NEXT VALUE FOR function
None of them include IIF, as Luis Cazares noted in their comment.
Your code indicates you do have a clue about what you are doing - maybe you forgot to put your IIF inside a SUM?

SQL aggregation query and sum columns

I have this table (I put the name over needed colums)
iddip date idv idc val
47 2018-06-01 00:00:00.000 0 3 3 60 NULL NULL
47 2018-06-01 00:00:00.000 0 1 3 200 NULL NULL
47 2018-06-01 00:00:00.000 0 1 4 280 NULL NULL
43 2018-06-01 00:00:00.000 0 3 2 510 NULL NULL
53 2018-06-01 00:00:00.000 0 1 4 480 NULL NULL
29 2018-06-01 00:00:00.000 0 3 2 510 NULL NULL
2 2018-06-11 00:00:00.000 0 1 2 480 NULL NULL
47 2018-06-02 00:00:00.000 0 1 3 100 NULL NULL
I want to obtain this:
id idc Totidv1 Totidv3 TOT
47 3 300 60 360
47 4 280 0 280
43 2 0 510 510
53 4 480 0 480
29 2 0 510 510
2 2 480 0 480
The closest I can get is:
SELECT DISTINCT(iddip),IDCENTROCOSTO,tot=SUM(VALORE),ord=( SELECT SUM(isnull(VALORE,0)) FROM VALORIVOCICDC WHERE IDVOCE='1' and iddip=v.IDDIP and IDCENTROCOSTO ='3' GROUP BY iddip,IDCENTROCOSTO),
str=( SELECT SUM(isnull(VALORE,0)) FROM VALORIVOCICDC WHERE IDVOCE='3' and iddip=v.IDDIP and IDCENTROCOSTO ='3' GROUP BY iddip,IDCENTROCOSTO)
FROM VALORIVOCICDC v
GROUP BY v.iddip,IDCENTROCOSTO
But it returns wrong sums in totidv1 and totisv3, How can I do this? Thanks for any hint
You just need a GROUP BY here (not distinct) and a couple of CASE statements:
SELECT
id,
idc,
SUM(CASE WHEN idv=3 THEN idv ELSE 0 END) as totidv1,
SUM(CASE WHEN idv=1 THEN idv ELSE 0 END) as totidv3,
SUM(idv) as Tot
FROM yourtable
GROUP BY id, idc
Note that Distinct is not a function that you can call like SELECT DISTINCT(somecolumn) This is functionally equivalent to SELECT DISTINCT somecolumn... in that it works against the entire record set returned by the SELECT statement either way.

SQL Server 2008 Pivot, no Aggregation, complex data

I've seen a lot of "Pivot, No Agg" posts, but all of them seem to involve some pretty simple data to pivot, so the solutions work fairly well and easily. But how about when the data isn't as simple?
I'd like to turn this:
wwnID Tenant WeekOfTheMonth ReportingDate TotalEmployeesPerBranch TotalOpenCount TotalClosedCount OpenCount_TitleAndEscrow ClosedCount_TitleAndEscrow OpenCount_EscrowOnly ClosedCount_EscrowOnly OpenCount_PreListingTask ClosedCount_PreListingTask OFPE CFPE OpenCount_TitleOnly ClosedCount_TitleOnly CurrentBusinessDay TotalBusinessDaysMTD ReportingDateId CreatedDate
----------- -------------------------------------------------- -------------- ----------------------- --------------------------------------- -------------- ---------------- ------------------------ -------------------------- -------------------- ---------------------- ------------------------ -------------------------- --------------------------------------- --------------------------------------- ------------------- --------------------- ------------------ -------------------- --------------- -----------------------
3 King 1 2014-08-08 00:00:00.000 144.00 235 0 137 0 64 0 34 0 4.81 0.00 270 0 7 21 411 2014-09-05 08:53:11.313
5 King 2 2014-08-15 00:00:00.000 150.00 399 0 224 0 112 0 63 0 4.62 0.00 524 0 12 21 412 2014-09-05 08:53:19.573
7 King 3 2014-08-22 00:00:00.000 150.00 584 0 335 0 159 0 90 0 4.76 0.00 721 0 17 21 413 2014-09-05 08:53:26.980
9 King 4 2014-08-31 00:00:00.000 150.00 797 0 436 0 226 0 135 0 5.18 0.00 946 0 21 21 414 2014-09-05 08:53:35.593
4 Pierce 1 2014-08-08 00:00:00.000 21.00 85 0 31 0 39 0 15 0 12.00 0.00 54 0 7 21 411 2014-09-05 08:53:11.670
6 Pierce 2 2014-08-15 00:00:00.000 22.00 160 0 62 0 74 0 24 0 12.41 0.00 83 0 12 21 412 2014-09-05 08:53:20.000
8 Pierce 3 2014-08-22 00:00:00.000 22.00 222 0 82 0 107 0 33 0 12.41 0.00 127 0 17 21 413 2014-09-05 08:53:27.407
10 Pierce 4 2014-08-31 00:00:00.000 23.00 272 0 99 0 130 0 43 0 10.96 0.00 159 0 21 21 414 2014-09-05 08:53:36.063
into this:
Data Types Week 1 Week 2 Week 3 Week 4
------------------------------- ----------- ----------- ----------- -----------
Tenant King King King King
ReportingDate 8/8/2014 8/15/2014 8/22/2014 8/31/2014
TotalEmployeesPerBranch 144 150 150 150
TotalOpenCount 235 399 584 797
TotalClosedCount 0 0 0 0
OpenCount_TitleAndEscrow 137 224 335 436
ClosedCount_TitleAndEscrow 0 0 0 0
OpenCount_EscrowOnly 64 112 159 226
ClosedCount_EscrowOnly 0 0 0 0
OpenCount_PreListingTask 34 63 90 135
ClosedCount_PreListingTask 0 0 0 0
OFPE 4.81 4.62 4.76 5.18
CFPE 0 0 0 0
OpenCount_TitleOnly 270 524 721 946
ClosedCount_TitleOnly 0 0 0 0
CurrentBusinessDay 7 12 17 21
TotalBusinessDaysMTD 21 21 21 21
ReportingDateId 411 412 413 414
CreatedDate 9/5/2014 9/5/2014 9/5/2014 9/5/2014
Tenant Pierce Pierce Pierce Pierce
ReportingDate 8/8/2014 8/15/2014 8/22/2014 8/31/2014
TotalEmployeesPerBranch 21 22 22 23
TotalOpenCount 85 160 222 272
TotalClosedCount 0 0 0 0
OpenCount_TitleAndEscrow 31 62 82 99
ClosedCount_TitleAndEscrow 0 0 0 0
OpenCount_EscrowOnly 39 74 107 130
ClosedCount_EscrowOnly 0 0 0 0
OpenCount_PreListingTask 15 24 33 43
ClosedCount_PreListingTask 0 0 0 0
OFPE 12 12.41 12.41 10.96
CFPE 0 0 0 0
OpenCount_TitleOnly 54 83 127 159
ClosedCount_TitleOnly 0 0 0 0
CurrentBusinessDay 7 12 17 21
TotalBusinessDaysMTD 21 21 21 21
ReportingDateId 411 412 413 414
CreatedDate 9/5/2014 9/5/2014 9/5/2014 9/5/2014
I've tried several methods of pivoting, and none of them seem to do the trick, but if anyone out there knows a way to do it, that'd be fantastic!
Thanks ahead of time!
UPDATE
This works beautifully! (initial variable declarations are for the where clause toward the end)
DECLARE #ReportDate DATETIME = '2014-08-31';
DECLARE #RepDateId INT = ( SELECT MAX([WRD].[ReportingDateID])
FROM [SMS].[dbo].[WSOBReportingDates] AS WRD
WHERE ( [WRD].[ReportingDate] <= #ReportDate )
AND ( [WRD].[Submitted] = 1 ) );
DECLARE #WSOBRepDate DATETIME = ( SELECT [WRD].[ReportingDate]
FROM [SMS].[dbo].[WSOBReportingDates] AS WRD
WHERE [WRD].[ReportingDateID] = #RepDateId );
DECLARE #WSOBStartDate DATETIME = DATEADD(mm, DATEDIFF(mm, 0, #WSOBRepDate), 0);
SELECT Datatype
, MAX(CASE WHEN WeekOfTheMonth = 1 THEN value ELSE '0' END) Week1
, MAX(CASE WHEN WeekOfTheMonth = 2 THEN value ELSE '0' END) Week2
, MAX(CASE WHEN WeekOfTheMonth = 3 THEN value ELSE '0' END) Week3
, MAX(CASE WHEN WeekOfTheMonth = 4 THEN value ELSE '0' END) Week4
FROM ( SELECT WeekOfTheMonth
, DataType
, Value
, SortOrder
, Sequence = ROW_NUMBER() OVER ( PARTITION BY WeekOfTheMonth ORDER BY wwnId )
FROM [dbo].[SSRS_WSOBWeeklyNumbers] AS SWWN
CROSS APPLY ( SELECT 'Tenant'
, [SWWN].[Tenant]
, 1
UNION ALL
SELECT 'ReportingDate'
, CONVERT(VARCHAR(10), [SWWN].[ReportingDate], 120)
, 2
UNION ALL
SELECT 'TotalEmployeesPerBranch'
, CAST([SWWN].[TotalEmployeesPerBranch] AS VARCHAR(10))
, 3
UNION ALL
SELECT 'TotalOpenCount'
, CAST([SWWN].[TotalOpenCount] AS VARCHAR(10))
, 4
UNION ALL
SELECT 'TotalClosedCount'
, CAST([SWWN].[TotalClosedCount] AS VARCHAR(10))
, 5
UNION ALL
SELECT 'OpenCount_TitleAndEscrow'
, CAST([SWWN].[OpenCount_TitleAndEscrow] AS VARCHAR(10))
, 6
UNION ALL
SELECT 'ClosedCount_TitleAndEscrow'
, CAST([SWWN].[ClosedCount_TitleAndEscrow] AS VARCHAR(10))
, 7
UNION ALL
SELECT 'OpenCount_EscrowOnly'
, CAST([SWWN].[OpenCount_EscrowOnly] AS VARCHAR(10))
, 8
UNION ALL
SELECT 'ClosedCount_EscrowOnly'
, CAST([SWWN].[ClosedCount_EscrowOnly] AS VARCHAR(10))
, 9
UNION ALL
SELECT 'OpenCount_PreListingTask'
, CAST([SWWN].[OpenCount_PreListingTask] AS VARCHAR(10))
, 10
UNION ALL
SELECT 'ClosedCount_PreListingTask'
, CAST([SWWN].[ClosedCount_PreListingTask] AS VARCHAR(10))
, 11
UNION ALL
SELECT 'OFPE'
, CAST([SWWN].[OFPE] AS VARCHAR(10))
, 12
UNION ALL
SELECT 'CFPE'
, CAST([SWWN].[CFPE] AS VARCHAR(10))
, 13
UNION ALL
SELECT 'OpenCount_TitleOnly'
, CAST([SWWN].[OpenCount_TitleOnly] AS VARCHAR(10))
, 14
UNION ALL
SELECT 'ClosedCount_TitleOnly'
, CAST([SWWN].[ClosedCount_TitleOnly] AS VARCHAR(10))
, 15
UNION ALL
SELECT 'CurrentBusinessDay'
, CAST([SWWN].[CurrentBusinessDay] AS VARCHAR(10))
, 16
UNION ALL
SELECT 'TotalBusinessDaysForMonth'
, CAST([SWWN].[TotalBusinessDaysMTD] AS VARCHAR(10))
, 17
UNION ALL
SELECT 'ReportingDateId'
, CAST([SWWN].[ReportingDateId] AS VARCHAR(10))
, 18
UNION ALL
SELECT 'CreatedDate'
, CAST([SWWN].[CreatedDate] AS VARCHAR(10))
, 19 ) c ( DataType, Value, SortOrder )
WHERE [SWWN].[ReportingDate] BETWEEN #WSOBStartDate AND #ReportDate ) d
GROUP BY DataType
, Sequence
, SortOrder
ORDER BY Sequence
, SortOrder;
and results in:
Datatype Week1 Week2 Week3 Week4
-------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------------------------------------
Tenant King King King King
ReportingDate 2014-08-08 2014-08-15 2014-08-22 2014-08-31
TotalEmployeesPerBranch 144.00 150.00 150.00 150.00
TotalOpenCount 235 399 584 797
TotalClosedCount 0 0 0 0
OpenCount_TitleAndEscrow 137 224 335 436
ClosedCount_TitleAndEscrow 0 0 0 0
OpenCount_EscrowOnly 64 112 159 226
ClosedCount_EscrowOnly 0 0 0 0
OpenCount_PreListingTask 34 63 90 135
ClosedCount_PreListingTask 0 0 0 0
OFPE 4.81 4.62 4.76 5.18
CFPE 0.00 0.00 0.00 0.00
OpenCount_TitleOnly 270 524 721 946
ClosedCount_TitleOnly 0 0 0 0
CurrentBusinessDay 7 12 17 21
TotalBusinessDaysForMonth 21 21 21 21
ReportingDateId 411 412 413 414
CreatedDate Sep 5 201 Sep 5 201 Sep 5 201 Sep 5 201
Tenant Pierce Pierce Pierce Pierce
ReportingDate 2014-08-08 2014-08-15 2014-08-22 2014-08-31
TotalEmployeesPerBranch 21.00 22.00 22.00 23.00
TotalOpenCount 85 160 222 272
TotalClosedCount 0 0 0 0
OpenCount_TitleAndEscrow 31 62 82 99
ClosedCount_TitleAndEscrow 0 0 0 0
OpenCount_EscrowOnly 39 74 107 130
ClosedCount_EscrowOnly 0 0 0 0
OpenCount_PreListingTask 15 24 33 43
ClosedCount_PreListingTask 0 0 0 0
OFPE 12.00 12.41 12.41 10.96
CFPE 0.00 0.00 0.00 0.00
OpenCount_TitleOnly 54 83 127 159
ClosedCount_TitleOnly 0 0 0 0
CurrentBusinessDay 7 12 17 21
TotalBusinessDaysForMonth 21 21 21 21
ReportingDateId 411 412 413 414
CreatedDate Sep 5 201 Sep 5 201 Sep 5 201 Sep 5 201
Thanks tons for the answer!
You'll need to UNPIVOT all those columns first, then convert your Weeks into new columns. But in order to UNPIVOT the data, you'll have to convert all of the data types to be the same.
Since you are using SQL Server 2008, you can use CROSS APPLY to unpivot. The basic syntax will be:
select
WeekOfTheMonth,
DataType,
Value
from yourtable
cross apply
(
select 'Tenant', Tenant union all
select 'ReportingDate', convert(varchar(10), ReportingDate, 120) union all
select 'TotalEmployeesPerBranch', cast(TotalEmployeesPerBranch as varchar(10)) union all
select 'TotalOpenCount', cast(TotalOpenCount as varchar(10)) union all
select 'TotalClosedCount', cast(TotalClosedCount as varchar(10)) union all
select 'OpenCount_TitleAndEscrow', cast(OpenCount_TitleAndEscrow as varchar(10)) union all
select 'ClosedCount_TitleAndEscrow', cast(ClosedCount_TitleAndEscrow as varchar(10)) union all
select 'OpenCount_EscrowOnly', cast(OpenCount_EscrowOnly as varchar(10)) union all
select 'ClosedCount_EscrowOnly', cast(ClosedCount_EscrowOnly as varchar(10)) union all
select 'OpenCount_PreListingTask', cast(OpenCount_PreListingTask as varchar(10))
--- union all more columns
) c (DataType, value);
See SQL Fiddle with Demo. Then you'd apply the PIVOT to your Weeks:
select DataType,
Week1 = [1],
Week2 = [2],
Week3 = [3],
Week4 = [4]
from
(
select
WeekOfTheMonth,
DataType,
Value,
so,
seq = row_number() over(partition by WeekOfTheMonth order by wwnId)
from yourtable
cross apply
(
select 'Tenant', Tenant, 1 union all
select 'ReportingDate', convert(varchar(10), ReportingDate, 120), 2 union all
select 'TotalEmployeesPerBranch', cast(TotalEmployeesPerBranch as varchar(10)), 3 union all
select 'TotalOpenCount', cast(TotalOpenCount as varchar(10)), 4 union all
select 'TotalClosedCount', cast(TotalClosedCount as varchar(10)), 5 union all
select 'OpenCount_TitleAndEscrow', cast(OpenCount_TitleAndEscrow as varchar(10)), 6 union all
select 'ClosedCount_TitleAndEscrow', cast(ClosedCount_TitleAndEscrow as varchar(10)), 7 union all
select 'OpenCount_EscrowOnly', cast(OpenCount_EscrowOnly as varchar(10)),8 union all
select 'ClosedCount_EscrowOnly', cast(ClosedCount_EscrowOnly as varchar(10)), 9 union all
select 'OpenCount_PreListingTask', cast(OpenCount_PreListingTask as varchar(10)), 10
) c (DataType, value, so)
) d
pivot
(
max(value)
for WeekOfTheMonth in ([1], [2], [3], [4])
)p
order by seq, so
See SQL Fiddle with Demo.
Or you can use an aggregate function to create the new columns:
select Datatype,
max(case when WeekOfTheMonth = 1 then value else '0' end) Week1,
max(case when WeekOfTheMonth = 2 then value else '0' end) Week2,
max(case when WeekOfTheMonth = 3 then value else '0' end) Week3,
max(case when WeekOfTheMonth = 4 then value else '0' end) Week4
from
(
select
WeekOfTheMonth,
DataType,
Value,
so,
seq = row_number() over(partition by WeekOfTheMonth order by wwnId)
from yourtable
cross apply
(
select 'Tenant', Tenant, 1 union all
select 'ReportingDate', convert(varchar(10), ReportingDate, 120), 2 union all
select 'TotalEmployeesPerBranch', cast(TotalEmployeesPerBranch as varchar(10)), 3 union all
select 'TotalOpenCount', cast(TotalOpenCount as varchar(10)), 4 union all
select 'TotalClosedCount', cast(TotalClosedCount as varchar(10)), 5 union all
select 'OpenCount_TitleAndEscrow', cast(OpenCount_TitleAndEscrow as varchar(10)), 6 union all
select 'ClosedCount_TitleAndEscrow', cast(ClosedCount_TitleAndEscrow as varchar(10)), 7 union all
select 'OpenCount_EscrowOnly', cast(OpenCount_EscrowOnly as varchar(10)),8 union all
select 'ClosedCount_EscrowOnly', cast(ClosedCount_EscrowOnly as varchar(10)), 9 union all
select 'OpenCount_PreListingTask', cast(OpenCount_PreListingTask as varchar(10)), 10
) c (DataType, value, so)
) d
group by datatype, seq, so
order by seq, so
See SQL Fiddle with Demo