Sum a Specific Column When Multiple Records Exist - tsql

I'm trying to sum a specific column to get a number total for each ID - but my result set is returning a result set that is a multiple of 6.
For example, the request_ID in my query has six docket_IDs associated with it and each docket_ID has six message_document_IDs associated.
Query:
SELECT r.id,
r.number_of_documents,
rc.docket_id,
rc.sequence_no,
rc.case_number_from_filer,
rd.number_of_pages,
rd.message_document_id,
r.received_date
FROM dbo.requests AS [r]
INNER JOIN dbo.request_court_documents_additonal_information AS [rc]
ON r.id = rc.request_id
INNER JOIN dbo.request_document_additonal_information AS [rd]
ON rd.request_id = r.id
WHERE CAST(r.received_date AS DATE) >= '10/1/2015'
AND CAST(r.received_date AS DATE) <= '9/30/2016'
AND rc.case_number_from_filer = 'NEW CASE'
AND r.id = 32700637
ORDER BY r.id,
rc.docket_id,
rd.message_document_id;
The data set looks like:
id docket_id case_number nbr_of_pgs msg_doc_id received_date
32700637 197085524 NEW CASE 18 DOC00001 2015-10-01 00:01:32.590
32700637 197085524 NEW CASE 1 DOC00002 2015-10-01 00:01:32.590
32700637 197085524 NEW CASE 4 DOC00003 2015-10-01 00:01:32.590
32700637 197085524 NEW CASE 9 DOC00004 2015-10-01 00:01:32.590
32700637 197085524 NEW CASE 9 DOC00005 2015-10-01 00:01:32.590
32700637 197085524 NEW CASE 3 DOC00006 2015-10-01 00:01:32.590
32700637 197085906 NEW CASE 18 DOC00001 2015-10-01 00:01:32.590
32700637 197085906 NEW CASE 1 DOC00002 2015-10-01 00:01:32.590
32700637 197085906 NEW CASE 4 DOC00003 2015-10-01 00:01:32.590
32700637 197085906 NEW CASE 9 DOC00004 2015-10-01 00:01:32.590
32700637 197085906 NEW CASE 9 DOC00005 2015-10-01 00:01:32.590
32700637 197085906 NEW CASE 3 DOC00006 2015-10-01 00:01:32.590
32700637 197085941 NEW CASE 18 DOC00001 2015-10-01 00:01:32.590
32700637 197085941 NEW CASE 1 DOC00002 2015-10-01 00:01:32.590
32700637 197085941 NEW CASE 4 DOC00003 2015-10-01 00:01:32.590
32700637 197085941 NEW CASE 9 DOC00004 2015-10-01 00:01:32.590
32700637 197085941 NEW CASE 9 DOC00005 2015-10-01 00:01:32.590
32700637 197085941 NEW CASE 3 DOC00006 2015-10-01 00:01:32.590
This repeats itself three more times - so I return 36 rows worth of data and when I try to SUM (rd.number_of_pages) - my result is 6 times what I am expecting: 264 when it should be 44.
SELECT r.id,
SUM(rd.number_of_pages) AS [Pages]
FROM dbo.requests AS [r]
INNER JOIN dbo.request_court_documents_additonal_information AS [rc]
ON r.id = rc.request_id
INNER JOIN dbo.request_document_additonal_information AS [rd]
ON rd.request_id = r.id
WHERE CAST(r.received_date AS DATE) >= '10/1/2015'
AND CAST(r.received_date AS DATE) <= '9/30/2016'
AND rc.case_number_from_filer = 'NEW CASE'
AND r.id = 32700637
GROUP BY r.id;
How can I eliminate the duplicate values from the docket_ids to return a true summation of the records?
Thanks,

Here's a way usint a correlated sub-query
if object_id('tempdb..#t') is not null drop table #t
create table #t (id int, docket_id int, case_number varchar(64), nbr_of_pgs int, msg_doc_id varchar(64), received_date datetime)
insert into #t values
(32700637,197085524,'NEW CASE',18,'DOC00001','2015-10-01 00:01:32.590'),
(32700637,197085524,'NEW CASE',1,'DOC00002','2015-10-01 00:01:32.590'),
(32700637,197085524,'NEW CASE',4,'DOC00003','2015-10-01 00:01:32.590'),
(32700637,197085524,'NEW CASE',9,'DOC00004','2015-10-01 00:01:32.590'),
(32700637,197085524,'NEW CASE',9,'DOC00005','2015-10-01 00:01:32.590'),
(32700637,197085524,'NEW CASE',3,'DOC00006','2015-10-01 00:01:32.590'),
(32700637,197085906,'NEW CASE',18,'DOC00001','2015-10-01 00:01:32.590'),
(32700637,197085906,'NEW CASE',1,'DOC00002','2015-10-01 00:01:32.590'),
(32700637,197085906,'NEW CASE',4,'DOC00003','2015-10-01 00:01:32.590'),
(32700637,197085906,'NEW CASE',9,'DOC00004','2015-10-01 00:01:32.590'),
(32700637,197085906,'NEW CASE',9,'DOC00005','2015-10-01 00:01:32.590'),
(32700637,197085906,'NEW CASE',3,'DOC00006','2015-10-01 00:01:32.590'),
(32700637,197085941,'NEW CASE',18,'DOC00001','2015-10-01 00:01:32.590'),
(32700637,197085941,'NEW CASE',1,'DOC00002','2015-10-01 00:01:32.590'),
(32700637,197085941,'NEW CASE',4,'DOC00003','2015-10-01 00:01:32.590'),
(32700637,197085941,'NEW CASE',9,'DOC00004','2015-10-01 00:01:32.590'),
(32700637,197085941,'NEW CASE',9,'DOC00005','2015-10-01 00:01:32.590'),
(32700637,197085941,'NEW CASE',3,'DOC00006','2015-10-01 00:01:32.590')
select distinct id, ct as TotalNum
from(
select distinct
id,
docket_id,
sum(nbr_of_pgs) as ct
from
#t
group by
id, docket_id)x
Your Query
select distinct id, pages
from(
SELECT
r.id,
rc.docket_id,
SUM(rd.number_of_pages) AS [Pages]
FROM dbo.requests AS [r]
INNER JOIN dbo.request_court_documents_additonal_information AS [rc]
ON r.id = rc.request_id
INNER JOIN dbo.request_document_additonal_information AS [rd]
ON rd.request_id = r.id
WHERE CAST(r.received_date AS DATE) >= '10/1/2015'
AND CAST(r.received_date AS DATE) <= '9/30/2016'
AND rc.case_number_from_filer = 'NEW CASE'
AND r.id = 32700637
GROUP BY r.id, rc.docket_id) x

Related

Parse custom tags In TSql

I have the following data in the csv and want to parse the tag elements to get the column and values from the tag.
1,{
"StudentLocs":["US","Kric"],
"Student_Service":["NY Volunteer"],
"Student_Unit":["Band1"],
"Student_enZone":["UTC"],
"Student_Geoloc":["Ind"],
"StudentRegisted":[FT"],
"StudentGender":["Male"],
"StudentName":["Sam"]
}
Expected output:
StudentId SLocs SService SUnit SenZone SGeoloc SRegisted SGender SName
1 US,Kric NY Volunteer Band1 UTC Ind FT Male Sam
Thanks for your help in advance !
For this you can use DelimitedSplit8K.
Against a single value:
DECLARE #string VARCHAR(8000) =
'1,{
"StudentLocs":["US","Kric"],
"Student_Service":["NY Volunteer"],
"Student_Unit":["Band1"],
"Student_enZone":["UTC"],
"Student_Geoloc":["Ind"],
"StudentRegisted":[FT"],
"StudentGender":["Male"],
"StudentName":["Sam"]
}';
SELECT
StudentId = MAX(CASE split.RN WHEN 0 THEN split.String END),
SLocs = MAX(CASE split.RN WHEN 2 THEN split.String END),
SService = MAX(CASE split.RN WHEN 3 THEN split.String END),
SUnit = MAX(CASE split.RN WHEN 4 THEN split.String END),
SenZone = MAX(CASE split.RN WHEN 5 THEN split.String END),
SGeoloc = MAX(CASE split.RN WHEN 6 THEN split.String END),
SRegisted = MAX(CASE split.RN WHEN 7 THEN split.String END),
SGender = MAX(CASE split.RN WHEN 8 THEN split.String END),
SName = MAX(CASE split.RN WHEN 9 THEN split.String END)
FROM
(
SELECT RN = 0, String = SUBSTRING(#string,1,CHARINDEX(',',#String)-1)
UNION ALL
SELECT s.ItemNumber, clean.string
FROM (VALUES(#string,CHARINDEX(',',#string))) AS f(String,B)
CROSS APPLY dbo.DelimitedSplit8K(f.String,CHAR(10)) AS s
CROSS APPLY (VALUES(CHARINDEX('":',s.item))) AS d(Pos)
CROSS APPLY (VALUES(CHARINDEX(CHAR(13),s.item))) AS v(E)
CROSS APPLY (VALUES(REPLACE(SUBSTRING(
s.item,d.Pos+3,v.E-d.Pos-5),'"',''))) AS clean(String)
WHERE d.Pos > 0
) AS split;
Returns:
SomeId StudentId SLocs SService SUnit SenZone SGeoloc SRegisted SGender SName
----------- ------------- ------------ --------------- ------ -------- -------- ---------- -------- ---------
1 1 US,Kric NY Volunteer Band1 UTC Ind FT Male Sam
Against a table:
-- Sample table
DECLARE #table TABLE (SomeId INT IDENTITY, String VARCHAR(8000));
INSERT #table (String) VALUES(
'1,{
"StudentLocs":["US","Kric"],
"Student_Service":["NY Volunteer"],
"Student_Unit":["Band1"],
"Student_enZone":["UTC"],
"Student_Geoloc":["Ind"],
"StudentRegisted":[FT"],
"StudentGender":["Male"],
"StudentName":["Sam"]
}'),
('1,{
"StudentLocs":["US","Chicago"],
"Student_Service":["Rock Star"],
"Student_Unit":["Band4"],
"Student_enZone":["XFS"],
"Student_Geoloc":["Ill"],
"StudentRegisted":[PT"],
"StudentGender":["Female"],
"StudentName":["Juliana"]
}');
SELECT t.SomeId, split.*
FROM #table AS t
CROSS APPLY
(
SELECT
StudentId = MAX(CASE split.RN WHEN 0 THEN split.String END),
SLocs = MAX(CASE split.RN WHEN 2 THEN split.String END),
SService = MAX(CASE split.RN WHEN 3 THEN split.String END),
SUnit = MAX(CASE split.RN WHEN 4 THEN split.String END),
SenZone = MAX(CASE split.RN WHEN 5 THEN split.String END),
SGeoloc = MAX(CASE split.RN WHEN 6 THEN split.String END),
SRegisted = MAX(CASE split.RN WHEN 7 THEN split.String END),
SGender = MAX(CASE split.RN WHEN 8 THEN split.String END),
SName = MAX(CASE split.RN WHEN 9 THEN split.String END)
FROM
(
SELECT RN = 0, String = SUBSTRING(t.String,1,CHARINDEX(',',t.String)-1)
UNION ALL
SELECT s.ItemNumber, clean.string
FROM (VALUES(t.string,CHARINDEX(',',t.String))) AS f(String,B)
CROSS APPLY dbo.DelimitedSplit8K(f.String,CHAR(10)) AS s
CROSS APPLY (VALUES(CHARINDEX('":',s.item))) AS d(Pos)
CROSS APPLY (VALUES(CHARINDEX(CHAR(13),s.item))) AS v(E)
CROSS APPLY (VALUES(REPLACE(SUBSTRING(
s.item,d.Pos+3,v.E-d.Pos-5),'"',''))) AS clean(String)
WHERE d.Pos > 0
) AS split
) AS split;
Returns:
SomeId StudentId SLocs SService SUnit SenZone SGeoloc SRegisted SGender SName
----------- ------------- ------------ --------------- ------ -------- -------- ---------- -------- ---------
1 1 US,Kric NY Volunteer Band1 UTC Ind FT Male Sam
2 1 US,Chicago Rock Star Band4 XFS Ill PT Female Juliana
One way to solve this, is to try to convert it to xml and parse that. something like the below:-
declare #d varchar(max)='1,{
"StudentLocs":["US","Kric"],
"Student_Service":["NY Volunteer"],
"Student_Unit":["Band1"],
"Student_enZone":["UTC"],
"Student_Geoloc":["Ind"],
"StudentRegisted":[FT"],
"StudentGender":["Male"],
"StudentName":["Sam"]
}'
Lets create a memory table to help in the convertion to xml, so we can make several replaces to original input.
Declare #replaceTable table(
id int identity(1,1),
item varchar(max), --item to find
[value] varchar(max) --item to replace with
)
insert into #replaceTable(item,[value]) values
(CHAR(13),''),(CHAR(10),''),
('StudentLocs:','</StudentId><StudentLocs>'),
('Student_Service:','</StudentLocs><Student_Service>'),
('Student_Unit:','</Student_Service><Student_Unit>'),
('Student_enZone:','</Student_Unit><Student_enZone>'),
('Student_Geoloc:','</Student_enZone><Student_Geoloc>'),
('StudentRegisted:','</Student_Geoloc><StudentRegisted>'),
('StudentGender:','</StudentRegisted><StudentGender>'),
('StudentName:','</StudentGender><StudentName>'),
('{',''),('}',''),('[',''),(']',''),('],',''),('"',''),(',{','')
declare #index int=(select COUNT(*) from #replaceTable)
set #d='<StudentId>'+#d+'</StudentName>' --some minor fix to the input
while(#index>0)--processing the replaces in desc order.
select #d=REPLACE(#d,item,[value]) ,#index=#index-1 from #replaceTable where id=#index
Declare #xml xml=#d
select
#xml.value('/StudentId[1]','int') StudentId,
#xml.value('/StudentLocs[1]','varchar(max)') SLocs ,
#xml.value('/Student_Service[1]','varchar(max)') SService ,
#xml.value('/Student_Unit[1]','varchar(max)') SUnit ,
#xml.value('/Student_enZone[1]','varchar(max)') SenZone ,
#xml.value('/Student_Geoloc[1]','varchar(max)') SGeoloc,
#xml.value('/StudentRegisted[1]','varchar(max)') SRegisted ,
#xml.value('/StudentGender[1]','varchar(max)') SGender ,
#xml.value('/StudentName[1]','varchar(max)') SName
The output will be as below:-
StudentId SLocs SService SUnit SenZone SGeoloc SRegisted SGender SName
1 US,Kric NY Volunteer Band1 UTC Ind FT Male Sam

Why is there a difference in my SQL output

This is puzzling me no end, and I know it might be tough without the data but thought it might be a longshot to post here.
Here goes, the first code I received was this
USE [Radiotherapy]
GO
if exists (
select * from tempdb.dbo.sysobjects o
where o.xtype in ('U')
and o.id = object_id(N'tempdb..#MySampleTemp')
)
DROP TABLE #MySampleTemp;
if exists (
select * from tempdb.dbo.sysobjects o
where o.xtype in ('U')
and o.id = object_id(N'tempdb..#MyPivotTemp')
)
DROP TABLE #MyPivotTemp;
SELECT [AttendanceNumber]
,CASE WHEN AgeAtExamDate BETWEEN 0 AND 5 THEN '0-5'
WHEN AgeAtExamDate BETWEEN 6 AND 18 THEN '6-18'
WHEN AgeAtExamDate BETWEEN 19 AND 150 THEN '19+'
ELSE 'Error' END AS AgeRange
,[LocalPatientIdentifier]
,[ExaminationDate]
,[ExamExaminationCode] INTO #MySampleTemp
FROM [dbo].[tblRadiologyData]
WHERE AttendanceSiteCode IN('CNM','RNM')
--AND AttendanceStatus NOT IN ( 'Appt', 'Booked In', 'Cancelled', 'Pending' )
--AND AttendancePatientGroup = 'Out Patient'
--AND AttendancePatientCategory IN ( 'EU', 'Military', 'N.H.S.' )
--AND AttendanceSourceName <> 'PACs Support'
AND [ExaminationDate] >= '1 OCTOBER 2015' --
ORDER BY [AttendanceNumber], CASE WHEN AgeAtExamDate BETWEEN 0 AND 5 THEN '0-5'
WHEN AgeAtExamDate BETWEEN 6 AND 18 THEN '6-18'
WHEN AgeAtExamDate BETWEEN 19 AND 150 THEN '19+'
ELSE 'Error' END, [LocalPatientIdentifier], [ExaminationDate], ExamExaminationCode
SELECT [AttendanceNumber],AgeRange,[LocalPatientIdentifier],[ExaminationDate], 1 AS ExamCount,
[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14] INTO #MyPivotTemp
FROM
(
SELECT *,
row_number() OVER(PARTITION BY [AttendanceNumber]
ORDER BY [AttendanceNumber], [LocalPatientIdentifier]) rn
FROM #MySampleTemp
) AS st
pivot
(
MAX(ExamExaminationCode)
FOR rn in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14])
) AS pivottable
SELECT
[1] AS Exam01,
[2] AS Exam02,
[3] AS Exam03,
[4] AS Exam04,
[5] AS Exam05,
[6] AS Exam06,
[7] AS Exam07,
[8] AS Exam08,
[9] AS Exam09,
[10] AS Exam10,
[11] AS Exam11,
[12] AS Exam12,
[13] AS Exam13,
[14] AS Exam14,
COUNT(ExamCount) AS [No. Attendances]
FROM #MyPivotTemp
GROUP BY [1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14]
ORDER BY [1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14]
What I tried to do was replicate this in query as follows:
USE [Radiotherapy]
;With CTE AS (SELECT s.attendanceNumber,
MAX(CASE WHEN s.rnk = 1 THEN s.ExamExaminationCode END) as examCode1,
MAX(CASE WHEN s.rnk = 2 THEN s.ExamExaminationCode END) as examCode2,
MAX(CASE WHEN s.rnk = 3 THEN s.ExamExaminationCode END) as examCode3,
MAX(CASE WHEN s.rnk = 4 THEN s.ExamExaminationCode END) as examCode4,
MAX(CASE WHEN s.rnk = 5 THEN s.ExamExaminationCode END) as examCode5,
MAX(CASE WHEN s.rnk = 6 THEN s.ExamExaminationCode END) as examCode6,
MAX(CASE WHEN s.rnk = 7 THEN s.ExamExaminationCode END) as examCode7,
MAX(CASE WHEN s.rnk = 8 THEN s.ExamExaminationCode END) as examCode8,
MAX(CASE WHEN s.rnk = 9 THEN s.ExamExaminationCode END) as examCode9,
MAX(CASE WHEN s.rnk = 10 THEN s.ExamExaminationCode END) as examCode10,
MAX(CASE WHEN s.rnk = 11 THEN s.ExamExaminationCode END) as examCode11,
MAX(CASE WHEN s.rnk = 12 THEN s.ExamExaminationCode END) as examCode12,
MAX(CASE WHEN s.rnk = 13 THEN s.ExamExaminationCode END) as examCode13,
MAX(CASE WHEN s.rnk = 14 THEN s.ExamExaminationCode END) as examCode14
FROM (
SELECT [AttendanceNumber]
,[ExaminationDate]
,[ExamExaminationCode]
,ROW_NUMBER() OVER(PARTITION BY [AttendanceNumber]
ORDER BY [RadiologyID]) as rnk --Ordered by date ASC
FROM [Radiotherapy].[dbo].[tblRadiologyData] rd
where rd.ExaminationDate >= '01 october 2015'
and rd.AttendanceSiteCode IN('CNM','RNM') ) s
GROUP BY s.attendanceNumber)
Select CTE.examCode1,
CTE.examCode2,
CTE.examCode3,
CTE.examCode4,
CTE.examCode5,
CTE.examCode6,
CTE.examCode7,
CTE.examCode8,
CTE.examCode9,
CTE.examCode10,
CTE.examCode11,
CTE.examCode12,
CTE.examCode13,
CTE.examCode14,
COUNT(CTE.AttendanceNumber) as [No of occurances]
from CTE
GROUP by CTE.examCode1,
CTE.examCode2,
CTE.examCode3,
CTE.examCode4,
CTE.examCode5,
CTE.examCode6,
CTE.examCode7,
CTE.examCode8,
CTE.examCode9,
CTE.examCode10,
CTE.examCode11,
CTE.examCode12,
CTE.examCode13,
CTE.examCode14
ORDER BY CTE.examCode1
Great I thought until my code returned more results which puzzled me. Having broken it down I found the offending code from the original query:
ORDER BY [AttendanceNumber], CASE WHEN AgeAtExamDate BETWEEN 0 AND 5 THEN '0-5'
WHEN AgeAtExamDate BETWEEN 6 AND 18 THEN '6-18'
WHEN AgeAtExamDate BETWEEN 19 AND 150 THEN '19+'
ELSE 'Error' END, [LocalPatientIdentifier], [ExaminationDate], ExamExaminationCode
When I removed this from the first query the results matched, but my question is how and why is an ORDER BY affecting the output. I assumed this was just showing how the results are ordered? Understanding why code is doing what it's doing is something I really need to get my head around. Any advise more than welcome.
Probably it have something to do with this piece of code:
SELECT *,
row_number() OVER(PARTITION BY [AttendanceNumber]
ORDER BY [AttendanceNumber], [LocalPatientIdentifier]) rn
FROM #MySampleTemp
Obviously your ordering is not breaking a tie(it isn't deterministic) and it produces rank number differently when you have ordered data in temp table and when not ordered. Try to add some PK to your temp table so the above code will look like:
SELECT *,
row_number() OVER(PARTITION BY [AttendanceNumber]
ORDER BY [AttendanceNumber], [LocalPatientIdentifier], [SomePK]) rn
FROM #MySampleTemp
Then removing ordering from first select statement will not have an effect on the result set.

Using an AND statement in a CASE in t sql

I am trying to make a case statement where one of the WHEN's contains an AND.
Declare #FROM DateTime = 'OCT 1 2015 12:00AM'
,case when isnull(SS.VerificationFlag,0) = 1 then 1
when isnull(SS.ExperationDate1,#FROM) >= #FROM AND isnull(SS.ExperationDate2,#FROM) >= #FROM then 1
else 0
END
I am getting a 1 as output when ExperationDate1 passes and ExperationDate2 fails.
Thank you.
There is nothing wrong with your case statement. I tried it in a select clause and it works as expected. I believe that you're getting a 1 because the first case is true. That is:
when isnull(SS.VerificationFlag,0) = 1 then 1
fires before you get to the more complicated clause with an AND statement.
DROP TABLE SS;
go
create table SS (
VerificationFlag tinyint,
ExpirationDate1 datetime,
ExpirationDate2 datetime
)
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (0, NULL, NULL)
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (0, '20140214', NULL)
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (0, NULL, '20160619')
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (0, '20140214', '20160619')
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (1, NULL, NULL)
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (1, '20140214', NULL)
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (1, NULL, '20160619')
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (1, '20140214', '20160619')
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (1, NULL, NULL)
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (1, '20160214', NULL)
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (1, NULL, '20140619')
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (1, '20160214', '20140619')
INSERT INTO SS(VerificationFlag, ExpirationDate1, ExpirationDate2) VALUES (0, '20160214', '20140619')
DECLARE #from DATETIME;
SET #from = '20151001';
SELECT
SS.VerificationFlag,
SS.ExpirationDate1,
SS.ExpirationDate2,
#from AS FromDate,
CASE
WHEN ISNULL(SS.VerificationFlag, 0) = 1 THEN 1
WHEN (ISNULL(SS.ExpirationDate1, #from) >= #from) AND (ISNULL(SS.ExpirationDate2, #from) >= #from) THEN 1
ELSE 0
END AS ResultingFlag
FROM SS
With results:
VerificationFlag ExpirationDate1 ExpirationDate2 FromDate ResultingFlag
---------------- ----------------------- ----------------------- ----------------------- -------------
0 NULL NULL 2015-10-01 00:00:00.000 1
0 2014-02-14 00:00:00.000 NULL 2015-10-01 00:00:00.000 0
0 NULL 2016-06-19 00:00:00.000 2015-10-01 00:00:00.000 1
0 2014-02-14 00:00:00.000 2016-06-19 00:00:00.000 2015-10-01 00:00:00.000 0
1 NULL NULL 2015-10-01 00:00:00.000 1
1 2014-02-14 00:00:00.000 NULL 2015-10-01 00:00:00.000 1
1 NULL 2016-06-19 00:00:00.000 2015-10-01 00:00:00.000 1
1 2014-02-14 00:00:00.000 2016-06-19 00:00:00.000 2015-10-01 00:00:00.000 1
1 NULL NULL 2015-10-01 00:00:00.000 1
1 2016-02-14 00:00:00.000 NULL 2015-10-01 00:00:00.000 1
1 NULL 2014-06-19 00:00:00.000 2015-10-01 00:00:00.000 1
1 2016-02-14 00:00:00.000 2014-06-19 00:00:00.000 2015-10-01 00:00:00.000 1
0 2016-02-14 00:00:00.000 2014-06-19 00:00:00.000 2015-10-01 00:00:00.000 0

Forming a Tsql query that ranks and categorizes date field

I have this datset:
create table #date_example
(
date_val datetime, rownum int
)
insert #date_example values('3/1/14',1)
insert #date_example values('3/1/14',2)
insert #date_example values('3/1/14',3)
insert #date_example values('2/1/14',4)
insert #date_example values('1/3/14',5)
select --top 1 with ties
date_val,
ROW_NUMBER() OVER(PARTITION BY rownum ORDER BY date_val DESC) AS 'RowNum'
from #date_example
order by date_val
desc
With output:
date_val RowNum
2014-03-01 00:00:00.000 1
2014-03-01 00:00:00.000 1
2014-03-01 00:00:00.000 1
2014-02-01 00:00:00.000 1
2014-01-03 00:00:00.000 1
But I want instead output:
date_val RowNum
2014-03-01 00:00:00.000 1
2014-03-01 00:00:00.000 1
2014-03-01 00:00:00.000 1
2014-02-01 00:00:00.000 2
2014-01-03 00:00:00.000 3
So I want the RowNum to be a ranking which includes ties. How can I do this?
I found the answer from another post:
select
date_val,
Rank() OVER(ORDER BY date_val DESC) AS 'RowNum'
from #date_example

Tsql unique records grouping

I am using SSMS 2008 R2 and I'm trying to condense output from this query into one line / full_name. How do I do this? Here is my query:
select top 500
CASE when pv.conversion_id_no is not null then pv.conversion_id_no else prv.id_no end as id_number,
eiev.full_name,
eiev.dob,
ep.start_date as yvdoa,
ep.end_date as yvdod,
e4pv.actual_date,
test_header_x.OUTCM_FLWUP_SRVY_PERIOD,
l.description as Call_Location,
case when tqav.question_caption like 'Custody at Follow-up%' then answer_caption end as Custody,
case when tqav.answer_caption like 'Residential Treatment Center%' then answer_is_selected end as RTC,
case when tqav.answer_caption like 'Psychiatric Hospital%' then answer_is_selected end as PsychHosp,
case when tqav.answer_caption like 'Juvenile Detention/Corrections or Adult Jail%' then answer_is_selected end as Corrections,
case when tqav.question_caption like 'Has the youth been attending school?%' then answer_caption end as AttendingSchool,
case when tqav.question_caption like 'Why is the youth not attending school%' then answer_caption end as SchoolStatus,
case when tqav.question_caption like 'Has youth been in trouble with the law/legal system%' then answer_caption end as TroubleLaw
from dbo.rpt_events_4people_view as e4pv
JOIN dbo.rpt_test_questions_answers_view as tqav on e4pv.event_log_id = tqav.event_log_id
left JOIN dbo.enrollment_info_expanded_view as eiev on eiev.people_id = e4pv.people_id
JOIN dbo.rpt_episod_of_care_program_view as ep on eiev.people_id = ep.people_id and ep.program_info_id = eiev.program_info
JOIN dbo.people_reports_view as prv on e4pv.people_id = prv.people_id
JOIN evolv_cs.dbo.test_details_answers_expanded_view as tdaev on tdaev.event_log_id = e4pv.event_log_id
JOIN evolv_cs.dbo.user_defined_lut as l ON tdaev.picklist_value = l.user_defined_lut_id
left outer JOIN dbo.people_rv as pv on eiev.people_id = pv.people_id
left JOIN [evolv_reports].[dbo].[test_header_rv] With (NoLock) ON e4pv.[event_log_id] = [test_header_rv].[event_log_id]
left JOIN evolv_cs.dbo.Test_header_x With (NoLock) ON test_header_x.test_header_id = test_header_rv.test_header_id
where e4pv.event_name = 'Outcome Follow-up Survey'
and e4pv.actual_date between '10/01/2011' and '03/31/2012'
and ep.program_name in ('In-Home Services - Intercept')
and (tqav.question_caption like 'Custody at Follow-up%' or
tqav.answer_caption like 'Residential Treatment Center%' or
tqav.answer_caption like 'Psychiatric Hospital%' or
tqav.answer_caption like 'Juvenile Detention/Corrections or Adult Jail%' or
tqav.question_caption like 'Has the youth been attending school?%' or
tqav.question_caption like 'Why is the youth not attending school%' or
tqav.question_caption like 'Has youth been in trouble with the law/legal system%' )
and ((eiev.profile_name like '%Lic.# NH%' and ep.start_date >= '02/01/2011')
or (eiev.profile_name like '%Lic.# MA%' and ep.start_date >= '02/01/2011')
or (eiev.profile_name like '%Lic.# DC%' and ep.start_date >= '05/01/2011')
or (eiev.profile_name like '%Lic.# NC%' and ep.start_date >= '05/01/2011')
or (eiev.profile_name like '%Lic.# FL%' and ep.start_date >= '07/18/2011')
or (eiev.profile_name like '%Lic.# TX%' and ep.start_date >= '07/18/2011')
or (eiev.profile_name like '%Lic.# AL%' and ep.start_date >= '02/01/2012')
or (eiev.profile_name like '%Lic.# GA%' and ep.start_date >= '02/01/2012')
or (eiev.profile_name like '%Lic.# OR%' and ep.start_date >= '03/01/2012'))
and DATEDIFF (dd,ep.start_date, ep.end_date) >= 60
Right now my output from this looks like:
id_number full_name dob yvdoa yvdod actual_date OUTCM_FLWUP_SRVY_PERIOD Call_Location Custody RTC PsychHosp Corrections AttendingSchool SchoolStatus TroubleLaw
10169613 Anderson, Mason 1996-02-06 00:00:00.000 2011-02-07 12:00:00.000 2011-09-04 23:59:00.000 2012-03-30 00:00:00.000 28094354-A0B4-428C-B38A-B90835DAF896 No Response Not available NULL NULL NULL NULL NULL NULL
10169613 Anderson, Mason 1996-02-06 00:00:00.000 2011-02-07 12:00:00.000 2011-09-04 23:59:00.000 2012-03-30 00:00:00.000 28094354-A0B4-428C-B38A-B90835DAF896 No Response NULL NULL NULL NULL NULL NULL NULL
10169613 Anderson, Mason 1996-02-06 00:00:00.000 2011-02-07 12:00:00.000 2011-09-04 23:59:00.000 2012-03-30 00:00:00.000 28094354-A0B4-428C-B38A-B90835DAF896 No Response NULL NULL NULL NULL NULL NULL NULL
10169613 Anderson, Mason 1996-02-06 00:00:00.000 2011-02-07 12:00:00.000 2011-09-04 23:59:00.000 2012-03-30 00:00:00.000 28094354-A0B4-428C-B38A-B90835DAF896 No Response NULL NULL NULL 0 NULL NULL NULL
10169613 Anderson, Mason 1996-02-06 00:00:00.000 2011-02-07 12:00:00.000 2011-09-04 23:59:00.000 2012-03-30 00:00:00.000 28094354-A0B4-428C-B38A-B90835DAF896 No Response NULL NULL 0 NULL NULL NULL NULL
10169613 Anderson, Mason 1996-02-06 00:00:00.000 2011-02-07 12:00:00.000 2011-09-04 23:59:00.000 2012-03-30 00:00:00.000 28094354-A0B4-428C-B38A-B90835DAF896 No Response NULL 0 NULL NULL NULL NULL NULL
So you will see that the answer fields can be VARCHAR values, which is why I can't simply SUM all of the answers.
Little-known fact: you can actually use MAX() to pick out the non-null varchar from your result set.
Suppose you have the following schema:
TABLE A:
a_id name
1 fruit
2 names
TABLE Vals:
a_id value_type value
1 a apple
1 b banana
1 c carrot
2 a alice
2 b bob
2 c carol
Then you can use MAX and GROUP BY to get one row per item in A listing each value type.
SELECT A.a_id,
A.name,
MAX(CASE WHEN V.value_type = 'a' then value end) as "a",
MAX(CASE WHEN V.value_type = 'b' then value end) as "b",
MAX(CASE WHEN V.value_type = 'c' then value end) as "c"
FROM A
INNER JOIN Vals V on V.a_id = A.a_id
GROUP BY A.a_id, A.name
See it on sqlfiddle here: http://sqlfiddle.com/#!3/aba0a/1