Generate Zeroes when no rows where selected - sql

Good Day Every one
i have this code
SELECT
'Expired Item -'+ DateName(mm,DATEADD(MM,4,AE.LOAN)) as [Month]
,COUNT(ISNULL(PIT.ID,0))'COUNT'
,SUM(ISNULL(PIT.KGRAM,0))'GRAMS'
,SUM(ISNULL(PH.AMOUNT,0))'PRINCIPAL'
FROM #AllExpired AE
INNER JOIN Transactions.ITEM PIT
ON AE.MAINID=PIT.MAINID
INNER JOIN Transactions.HISTO PH
ON AE.MAINID=PH.MAINID
GROUP BY DATENAME(MM,(DATEADD(MM,4,AE.LOAN)))
UNION ALL
/*SELECT EXPIRED AFTER 5 MONTHS*/
SELECT
'Expired Item -'+ DateName(mm,DATEADD(MM,5,AE.LOAN)) as [Month]
,COUNT(ISNULL(PIT.ID,0))'COUNT'
,SUM(ISNULL(PIT.KGRAM,0))'GRAMS'
,SUM(ISNULL(PH.AMOUNT,0))'PRINCIPAL'
FROM #ExpAfterFiveMonths E5
INNER JOIN Transactions.ITEM PIT
ON E5.MAINID=PIT.MAINID
INNER JOIN Transactions.HISTO PH
ON E5.MAINID=PH.MAINID
INNER JOIN #AllExpired AE
ON AE.MAINID=E5.MAINID
GROUP BY DATENAME(MM,(DATEADD(MM,5,AE.LOAN)))
UNION ALL
/*SELECT EXPIRED AFTER 6 MONTHS*/
SELECT
'Expired Item -'+ DateName(mm,DATEADD(MM,6,AE.LOAN)) as [Month]
,COUNT(ISNULL(PIT.ID,0))'COUNT'
,SUM(ISNULL(PIT.KGRAM,0))'GRAMS'
,SUM(ISNULL(PH.AMOUNT,0))'PRINCIPAL'
FROM #ExpAfterSixMonths E6
INNER JOIN Transactions.ITEM PIT
ON E6.MAINID=PIT.MAINID
INNER JOIN Transactions.HISTO PH
ON E6.MAINID=PH.MAINID
INNER JOIN #AllExpired AE
ON AE.MAINID=E6.MAINID
GROUP BY DATENAME(MM,(DATEADD(MM,6,AE.LOAN)))
and it works fine, the problem is that when the Select statements retrieved no rows they become empty instead of replacing zeroes
instead of Generating the word month with 0 0 0 it just pops out empty in which i dont like,,
can you help me achive that? the result should be something like this
------------------------------------------------------------------
MONTH | Count | Grams | Principal |
October |123123 | 123123 | 123123213 |
November | 0 | 0 | 0 | // this should appear if no rows where selected instead of blank
here is my code to generate the items inside temptables
SELECT TE.MAINID
,TE.EXPIRY
,TE.LOAN
,PM.STORAGE
into #AllExpiredAfterFiveAndSix
FROM #ExpiredAfterFiveandSixMon TE
inner join Transactions.TABLEMAIN PM
on TE.MAINID = PM.MAINID
inner join #AllExpired E4
on E4.MAINID=TE.MAINID
WHERE ((cast(TE.EXPIRY as date) < cast(TE.newloandate as date))
OR(TE.NewLoanDate is null and ((cast(TE.EXPIRY as date) < cast(PM.DATERED as date)) or PM.STATUS = 7 or PM.STATUS = 5)) )
AND (PM.STORAGE BETWEEN 3 AND 14 OR PM.STORAGE=17)
/*EXPIRED AFTER 5 MONTHS*/
select AE.MAINID
,AE.LOAN
,AE.STORAGE
,ae.EXPIRY
into #ExpAfterFiveMonths
from #AllExpiredAfterFiveAndSix AE
inner join #AllExpired E4
on E4.MAINID=AE.MAINID
where MONTH(AE.EXPIRY)= MONTH(dateadd(mm,1,E4.EXPIRY))
/*EXPIRED AFTER 6 MONTHS*/
select AE.MAINID
,AE.LOAN
,AE.STORAGE
,ae.EXPIRY
into #ExpAfterSixMonths
from #AllExpiredAfterFiveAndSix AE
inner join #AllExpired E4
on E4.MAINID=AE.MAINID
where MONTH(AE.EXPIRY)= MONTH(dateadd(mm,2,E4.EXPIRY))
CREATE NONCLUSTERED INDEX IDX_ExpAfterFiveMonths ON #ExpAfterFiveMonths(MAINID)
CREATE NONCLUSTERED INDEX IDX_ExpAfterSixMonths ON #ExpAfterSixMonths(MAINID)
i hope you can help me because im just a starter in sql
i have tried using is NULL as what you have seen above but i do not know if i implement it correctly
Hoping for your Kindness and consideration thank you :)
****EDIT**
The temp tables contains no values to start with, i just want it to output 0 instead of blank.

Edited: Added a months table to handle empty temp tables.
Change inner joins to left joins.
DECLARE #months TABLE (ReportMonth VARCHAR(20) NOT NULL)
INSERT INTO #months VALUES
('January'),('February'),('March'),('April'),
('May'),('June'),('July'),('August'),
('September'),('October'),('November'),('December')
SELECT
'Expired Item -'+ COALESCE(DateName(mm,DATEADD(MM,4,AE.fld_LoanDate)), M.ReportMonth) as [Month]
,COUNT(ISNULL(PIT.fld_PawnItemID,0))'COUNT'
,SUM(ISNULL(PIT.fld_KaratGram,0))'GRAMS'
,SUM(ISNULL(PH.fld_PrincipalAmt,0))'PRINCIPAL'
FROM
#months M
LEFT JOIN #AllExpired AE
ON M.ReportMonth = DateName(mm,DATEADD(MM,4,AE.fld_LoanDate))
LEFT JOIN Transactions.tbl_PawnItem PIT
ON AE.fld_PawnMainID=PIT.fld_PawnMainID
LEFT JOIN Transactions.tbl_PawnHisto PH
ON AE.fld_PawnMainID=PH.fld_PawnMainID
GROUP BY M.ReportMonth
UNION ALL
/*SELECT EXPIRED AFTER 5 MONTHS*/
SELECT
'Expired Item -'+ 'Expired Item -'+ COALESCE(DateName(mm,DATEADD(MM,5,AE.fld_LoanDate)), M.ReportMonth) as [Month]
,COUNT(ISNULL(PIT.fld_PawnItemID,0))'COUNT'
,SUM(ISNULL(PIT.fld_KaratGram,0))'GRAMS'
,SUM(ISNULL(PH.fld_PrincipalAmt,0))'PRINCIPAL'
FROM
#months M
LEFT JOIN #AllExpired AE
ON M.ReportMonth = DateName(mm,DATEADD(MM,5,AE.fld_LoanDate))
LEFT JOIN #ExpAfterFiveMonths E5
ON AE.fld_PawnMainID=E5.fld_PawnMainID
LEFT JOIN Transactions.tbl_PawnItem PIT
ON E5.fld_PawnMainID=PIT.fld_PawnMainID
LEFT JOIN Transactions.tbl_PawnHisto PH
ON E5.fld_PawnMainID=PH.fld_PawnMainID
GROUP BY M.ReportMonth
UNION ALL
/*SELECT EXPIRED AFTER 6 MONTHS*/
SELECT
'Expired Item -'+ COALESCE(DateName(mm,DATEADD(MM,6,AE.fld_LoanDate)), M.ReportMonth) as [Month]
,COUNT(ISNULL(PIT.fld_PawnItemID,0))'COUNT'
,SUM(ISNULL(PIT.fld_KaratGram,0))'GRAMS'
,SUM(ISNULL(PH.fld_PrincipalAmt,0))'PRINCIPAL'
FROM
#months M
LEFT JOIN #AllExpired AE
ON M.ReportMonth = DateName(mm,DATEADD(MM,6,AE.fld_LoanDate))
LEFT JOIN #ExpAfterSixMonths E6
ON AE.fld_PawnMainID=E6.fld_PawnMainID
LEFT JOIN Transactions.tbl_PawnItem PIT
ON E6.fld_PawnMainID=PIT.fld_PawnMainID
LEFT JOIN Transactions.tbl_PawnHisto PH
ON E6.fld_PawnMainID=PH.fld_PawnMainID
GROUP BY M.ReportMonth

Try this in your select
SELECT (CASE WHEN (AE.fld_LoanDate IS null) THEN 0 ELSE AE.fld_LoanDate END) as fld_LoanDate

Though both answers do what the questioner wanted, I though I would suggest 'where LoanDate in (range)', 'group by', along with left join, and a date range.
So, you have tables like this:
CREATE TABLE tPawnItem
(
fPawnItemID int auto_increment primary key,
fDescription varchar(30),
fKaratGram float
);
CREATE TABLE tPawnHisto
(
fPawnMainID int primary key,
fPrincipalAmt int,
fRedeemed date
);
create table tExp
(
fPawnMainID int primary key,
fLoanDate date
);
This is proximately what I'm suggesting (I don't have my laptop, so no mysql right now),
SELECT
'Expired Item -'+ DATENAME(MM,tExp.fLoanDate) as [Month]
,COUNT(ISNULL(tPawnItem.fPawnItemID,0))'COUNT'
,SUM(ISNULL(tPawnItem.fKaratGram,0))'GRAMS'
,SUM(ISNULL(tPawnHisto.fPrincipalAmt,0))'PRINCIPAL'
FROM tExp
INNER JOIN tPawnItem
ON tExp.fPawnMainID=tPawnItem.fPawnMainID
INNER JOIN tPawnHisto
ON tExp.fPawnMainID=tPawnHisto.fPawnMainID
WHERE t.Exp.fLoanDate in (
DATENAME(MM,DATEADD(MM,4,tExp.fLoanDate)),
DATENAME(MM,DATEADD(MM,5,tExp.fLoanDate)),
DATENAME(MM,DATEADD(MM,6,tExp.fLoanDate)),
DATENAME(MM,DATEADD(MM,7,tExp.fLoanDate))
)
GROUP BY DATENAME(MM,tExp.fLoanDate);

Related

Not does not exclude query info

I have a really long query and I'm finding that my NOT is not excluding what's in parenthesis after the NOT.
I saw Exclude and where not exists, but I'd have to re-select for that, and there's too many complicatedly joined tables in what I selected already, plus one table is very big and takes a long time to select what I have already, so I can't re-select because it will make the query take too long. How do I get this exclusion to work?
INSERT INTO #UNeedingC(id, CASEID, firstname, lastname, userid, AGEOFNOTIFICATION, DATETIMEDECISIONMADE, DELEGATESYSTEM, Person_id, request_type_id, service_place_id, status_summary, externalUserId, subject, onDate, externalPersonId, externalSystemId)
select distinct
c.id
,uc.case_id
,t_case.FIRSTNAME as first
,t_case.LASTNAME as last
,t_case.user_id as userid
,CONVERT(VARCHAR, DATEDIFF(dd, SC.status_change_date, GETDATE())) + ' Day(s) ' + CONVERT(VARCHAR, DATEDIFF(hh, SC.status_change_date, GETDATE()) % 24) + ' Hour(s) ' as [AGE OF NOTIFICATION]
,SC.status_change_date AS [DATE TIME DECISION MADE]
,[ckoltp_sys].DBO.ckfn_GetStringLocaleValue(152,9,uc.delegate_system,50,0) AS [DELEGATESYSTEM]
,c.person_id
,uc.request_type_id ------
,uc.service_place_id
,uc.status_summary
,eou.external_id
,c.tzix_id+' '+[ckoltp_sys].dbo.ckfn_GetStringLocaleValue(148,9,uc.status_summary,5,0)+' type' AS subject
,dateadd( hour,41,dateadd(day,0,datediff(d,0,sc.status_change_date)) ) AS onDate
,emd.externalId externalPersonId
,eou.system_id as externalSystemId
--,u.disable
from
#tempC t_case with (NOLOCK)
inner join dbo.org_case c with (nolock) ON t_case.Person_id=c.Person_id
INNER JOIN dbo.org_2_case uc with (NOLOCK) ON uc.case_id=c.id
inner JOIN dbo.ORG_LOS S WITH (NOLOCK) ON S.case_id = UC.case_id
inner JOIN dbo.ORG_EXTENSION SC WITH (NOLOCK) ON SC.los_id= S.id
inner join dbo.org_user u with (NOLOCK) on u.id=t_case.user_id
inner join dbo.org_person op with (NOLOCK) on op.id=c.Person_id
inner JOIN dbo.u_person_concept_value MC ON MC.CID = op.cid --this is the slow table
inner join dbo.EXTERNAL_ORG_USER_DATA eou with (NOLOCK) ON eou.org_user_id = t_case.user_id
inner join dbo.EXTERNAL_person_DATA emd with (NOLOCK) ON emd.CID = op.cid --op.id --?
WHERE
DATEDIFF(day, SC.status_change_date , GETDATE()) <= 2
AND
u.disable <> 1
AND
( --(denied/approved)
dbo.ckfn_GetStringLocaleValue(148,9,uc.status_summary,5,0) = 'Denied'
OR
(dbo.ckfn_GetStringLocaleValue(148,9,uc.status_summary,5,0) in( 'Fully Approved', 'Partially Approved'))
)
AND
(
(
ISNULL(uc.request_type_id,'') in( 12)
AND DATEDIFF(month, SC.status_change_date , GETDATE()) <= 2
)
OR
(
ISNULL(uc.request_type_id,'') in( 10,11)
)
--OR
--(
-- --exclude this
-- (
-- MC.concept_id = '501620' --general val1 (1000/1001)
-- AND
-- (C.ID in (select case_id from #CASES where str_value in ('1000','1001'))
-- AND (uc.service_place_id = 31 OR uc.service_place_id = 32))
-- ) --not
--) --or
)--AND
AND
(t_case.firstname not like '%external%' and t_case.lastname not like '%case manager%')
AND
(
C.ID in (select case_id from #CASES where concept_id='501620')--MC.concept_id = '501620'
)
--overall around AND (denied/approved)--
and DBO.ckfn_GetStringLocaleValue(152,9,uc.delegate_system,50,0) in ('AP','CA')
AND NOT --this not is not working...this appears in query results
(
--exclude these
(
MC.concept_id = '501620'
AND
(C.ID in (select case_id from #CASES where str_value in ('1000','1001'))
AND (uc.service_place_id = 31 OR uc.service_place_id = 32))
) --not
) --
select * from #UNeedingC
results show what is excluded:
id caseid firstname lastname userid ageofNotification Datetimedecisionmade DelegateSys Person_id request_type_id service_place_id status_summary externalUserId subject
onDate externalPersonId externalSystemId
000256200 256200 Sree Par 1234 0 Apr 5 CA
4270000 11 31 3 sparee 000256200 Fully Approved tested Ad 2021-04-06 17:00 363000 2
My question: do you know why the NOT is not working and how I can get this to exclude without another select? See "this not is not working" comment. I searched online but only found exclude and where not exists, which require another select, which I don't want.
I think I figured it out: "NOT acts on one condition. To negate two or more conditions, repeat the NOT for each condition,"
from not on two things.
This seems to work:
...
AND
--exclude these
(
MC.concept_id = '501620' --general val1 (1000/1001)
AND
(C.ID not in (select case_id from #CASES where str_value in ('1000','1001'))
AND (uc.service_place_id not in ('31','32')))
) --not

Creating Daily In-Use table w/ Zeros When NULL

Hello Stack Community,
I am not sure if I titled this accurately, but I am attempting to create a table that tracks the daily in-use quantity by product code. Currently my code drops dates where a product isn't in-use whereas I need that to show as a 0.
My thoughts where that by using the date from the date table that my LEFT OUTER JOIN with the ISNULL on the field would produce a 0, but nay.
Here is my code, with a screenshot of what it outputs with the red square highlighting where it's missing date records that I need to show as 0 :
SELECT
DD.DATE,
DE.PRODUCT_CODE,
--OOC = OUT OF CONTEXT, EITHER ISN'T CHARGEABLE OR ISN'T CURRENTLY ACTIVE
ISNULL(SUM(LIDV.QTY - LIDV.QTYSUB),0),
OD.LOCATION,
OD.SOURCE
FROM Dim_Date AS DD
LEFT OUTER JOIN ORDERv_DatesDays AS OD ON DD.DATE BETWEEN OD.SHIP_DATE AND OD.adjRETURN_DATE
LEFT OUTER JOIN FACT_Orders_LIDs AS LIDV ON LIDV.SORDERID_DAX = OD.SORDERID_DAX
LEFT OUTER JOIN DIM_ECODES AS DE ON DE.PRODUCT_CODE = LIDV.eCODE
WHERE
--DD.DATE = '3/1/2017' AND
DD.DATE BETWEEN '1/1/2017' AND EOMONTH( DATEADD( MONTH , -1, CURRENT_TIMESTAMP ) ) AND
DE.PRODUCT_CODE = '07316-' AND
YEAR(DD.DATE) = 2017
GROUP BY
DD.DATE,
DE.PRODUCT_CODE,
OD.LOCATION,
OD.SOURCE
ORDER BY
DD.DATE
I also thought, since I'm no SQL expert, that perhaps I need to just create a table with each product code and date for a specified date range but I got tripped up trying to create that as well.
Thank you for any assistance, if I need to add more info just let me know what I'm missing.
This WHERE predicate is killing your left join:
DE.PRODUCT_CODE = '07316-' AND
If product_code 07316 was not "out on loan" (or whatever) between Feb 24 and April 6 then all those rows would have looked like:
DATE PRODUCT_CODE INUSE LOCATION
2017-02-25 NULL NULL NULL
2017-02-26 NULL NULL NULL
2017-02-27 NULL NULL NULL
2017-02-28 NULL NULL NULL
...
2017-04-05 NULL NULL NULL
But, that NULL in product_code means that when the where clause asks "is NULL equal to 07316- ?" the answer is false, so the row diasppears from the resultset
Consider
LEFT OUTER JOIN DIM_ECODES AS DE
ON
DE.PRODUCT_CODE = LIDV.eCODE AND
DE.PRODUCT_CODE = '07316-'
You might also want to make some changes in the SELECT block too:
'07316-' as PRODUCT_CODE,
COALESCE(INUSE,0) AS INUSE
It might make more sense to you to write it like this:
FROM
Dim_Date AS DD
LEFT OUTER JOIN
(
SELECT
OD.SHIP_DATE,
OD.adjRETURN_DATE,
LIDV.QTY,
LIDV.QTYSUB,
OD.LOCATION,
OD.SOURCE
FROM
ORDERv_DatesDays AS OD
INNER JOIN FACT_Orders_LIDs AS LIDV ON LIDV.SORDERID_DAX = OD.SORDERID_DAX
INNER JOIN DIM_ECODES AS DE ON DE.PRODUCT_CODE = LIDV.eCODE
WHERE
DE.PRODUCT_CODE = '07316-'
) x
ON DD.DATE BETWEEN x.SHIP_DATE AND x.adjRETURN_DATE
WHERE
This is "list of dates on the left" and "any relevant data, already joined together and where'd on the right"
It should also be noted that if you're doing this for multiple product codes, to prevent just a single date row if both product 07316 and 07317 are in use on the 28th Feb you'd need to:
FROM
(
SELECT DISTINCT DD.DATE, DE.PRODUCT_CODE
FROM Dim_Date AS DD CROSS JOIN DIM_ECODES DE
WHERE ..date range clause..
)
This takes your list of dates, and crosses it with your list of prod codes, so you can be certain there are at least these two rows:
2017-02-28 07316-
2017-02-28 07317-
Then when you left join the products on date and product code, both those rows' data survive the left join, and become associated with nulls:
2017-02-28 07316- NULL NULL
2017-02-28 07317- NULL NULL
Without doing that CROSS, you'd have just one row (null in product code)

SQL statement merge two rows into one

In the results of my sql-statement (SQL Server 2016) I would like to combine two rows with the same value in two columns ("study_id" and "study_start") into one row and keep the row with higest value in a third cell ("Id"). If any columns (i.e. "App_id" or "Date_arrival) in the row with higest Id is NULL, then it should take the value from the row with the lowest "Id".
I get the result below:
Id study_id study_start Code Expl Desc Startmonth App_id Date_arrival Efter_op Date_begin
167262 878899 954 4.1 udd.ord Afbrudt feb 86666 21-06-2012 N 17-08-2012
180537 878899 954 1 Afsluttet Afsluttet feb NULL NULL NULL NULL
And I would like to get this result:
Id study_id study_start Code Expl Desc Startmonth App_id Date_arrival Efter_op Date_begin
180537 878899 954 1 Afsluttet Afsluttet feb 86666 21-06-2012 N 17-08-2012
My statement looks like this:
SELECT dbo.PopulationStam_V.ELEV_ID AS id,
dbo.PopulationStam_V.PERS_ID AS study_id,
dbo.STUDIESTARTER.STUDST_ID AS study_start,
dbo.Optagelse_Studiestatus.AFGANGSARSAG AS Code,
dbo.Optagelse_Studiestatus.KORT_BETEGNELSE AS Expl,
ISNULL((CAST(dbo.Optagelse_Studiestatus.Studiestatus AS varchar(20))), 'Indskrevet') AS 'Desc',
dbo.STUDIESTARTER.OPTAG_START_MANED AS Startmonth,
dbo.ANSOGNINGER.ANSOG_ID as App_id,
dbo.ANSOGNINGER.ANKOMSTDATO AS Data_arrival',
dbo.ANSOGNINGER.EFTEROPTAG AS Efter_op,
dbo.ANSOGNINGER.STATUSDATO AS Date_begin
FROM dbo.INSTITUTIONER
INNER JOIN dbo.PopulationStam_V
ON dbo.INSTITUTIONER.INST_ID = dbo.PopulationStam_V.SEMI_ID
LEFT JOIN dbo.ANSOGNINGER
ON dbo.PopulationStam_V.ELEV_ID = dbo.ANSOGNINGER.ELEV_ID
INNER JOIN dbo.STUDIESTARTER
ON dbo.PopulationStam_V.STUDST_ID_OPRINDELIG = dbo.STUDIESTARTER.STUDST_ID
INNER JOIN dbo.UDD_NAVNE_T
ON dbo.PopulationStam_V.UDDA_ID = dbo.UDD_NAVNE_T.UDD_ID
INNER JOIN dbo.UDDANNELSER
ON dbo.UDD_NAVNE_T.UDD_ID = dbo.UDDANNELSER.UDDA_ID
LEFT OUTER JOIN dbo.PERSONER
ON dbo.PopulationStam_V.PERS_ID = dbo.PERSONER.PERS_ID
LEFT OUTER JOIN dbo.POSTNR
ON dbo.PERSONER.PONR_ID = dbo.POSTNR.PONR_ID
LEFT OUTER JOIN dbo.KønAlleElevID_V
ON dbo.PopulationStam_V.ELEV_ID = dbo.KønAlleElevID_V.ELEV_ID
LEFT OUTER JOIN dbo.Optagelse_Studiestatus
ON dbo.PopulationStam_V.AFAR_ID = dbo.Optagelse_Studiestatus.AFAR_ID
LEFT OUTER JOIN dbo.frafaldsmodel_adgangsgrundlag
ON dbo.frafaldsmodel_adgangsgrundlag.ELEV_ID = dbo.PopulationStam_V.ELEV_ID
LEFT OUTER JOIN dbo.Optagelse_prioriteterUFM
ON dbo.Optagelse_prioriteterUFM.cpr = dbo.PopulationStam_V.CPR_NR
AND dbo.Optagelse_prioriteterUFM.Aar = dbo.frafaldsmodel_adgangsgrundlag.optagelsesaar
LEFT OUTER JOIN dbo.frafaldsmodel_stoettetabel_uddannelser AS fsu
ON fsu.id_uddannelse = dbo.UDDANNELSER.UDDA_ID
AND fsu.id_inst = dbo.INSTITUTIONER.INST_ID
AND fsu.uddannelse_aar = dbo.frafaldsmodel_adgangsgrundlag.optagelsesaar
WHERE dbo.STUDIESTARTER.STUDIESTARTSDATO > '2012-03-01 00:00:00.000'
AND (dbo.Optagelse_Studiestatus.AFGANGSARSAG IS NULL
OR dbo.Optagelse_Studiestatus.AFGANGSARSAG NOT LIKE '2.7.4')
AND (dbo.PopulationStam_V.INDSKRIVNINGSFORM = '1100'
OR dbo.PopulationStam_V.INDSKRIVNINGSFORM = '1700')
GROUP BY dbo.PopulationStam_V.ELEV_ID,
dbo.PopulationStam_V.PERS_ID,
dbo.STUDIESTARTER.STUDST_ID,
dbo.Optagelse_Studiestatus.AFGANGSARSAG,
dbo.Optagelse_Studiestatus.KORT_BETEGNELSE,
dbo.STUDIESTARTER.OPTAG_START_MANED,
Studiestatus,
dbo.ANSOGNINGER.ANSOG_ID,
dbo.ANSOGNINGER.ANKOMSTDATO,
dbo.ANSOGNINGER.EFTEROPTAG,
dbo.ANSOGNINGER.STATUSDATO
I really hope somebody out there can help.
Many ways, this will work:
WITH subSource AS (
/* Your query here */
)
SELECT
s1.id,
/* all other columns work like this:
COALESCE(S1.column,s2.column)
for example: */
coalesce(s1.appid,s2.appid) as appid
FROM subSource s1
INNER JOIN subSource s2
ON s1.study_id =s2.study_id
and s1.study_start = s2.study_start
AND s1.id > s2.id
/* I imagine some other clauses might be needed but maybe not */
The rest is copy paste

Manipulating SQL table

I have a table, the structure of which I have simplified to the smaller table below.
I want to manipulate the dataset below into the following form:
The new dataset will contain a single record for each case of DC, with a yes/no flag indicating if the NatureOfTumour has changed from DC to IN, and the time taken to change from DC to IN if applicable.
The change from DC to IN will be considered only if location has remained the same i.e. only those records should be considered where NatureOfTumour has changed from DC to IN and the location remained the same. ItemNo is the unique ID.
On a community member's advice I have pasted the table in text below as well, cleaned up as best as I could. The last column "Gen" is empty. ItemNo is the unique ID. Copying the text below to excel and doing a text-to-columns (separated by spaces) should give you the original table in a readable format. Sorry cant think of a better way to paste the table here.
ItemNo DateOfTest NatureOfTumour Location Centre Gen
2345 07/2006 DC P S-224
2345 12/2006 IN P S-224
2342 05/2004 DC Q B-266
3878 06/2006 DC P S-224
3878 05/2005 DC Q S-224
5678 09/2000 IN P S-224
5597 10/2001 DC P B-266
5597 01/1999 IN Q B-266
Try this. The LEAD function looks at the next row based on groups of ItemNo ordered by DateOfTest.
WITH abc AS (
SELECT
ItemNo
,DateOfTest
,NatureOfTumour
,Location
,Centre
,LEAD(NatureOfTumour) OVER (PARTITION BY ItemNo ORDER BY DateOfTest) as FutureNature
,LEAD(Location) OVER (PARTITION BY ItemNo ORDER BY DateOfTest) as FutureLocation
,LEAD(DateOfTest) OVER (PARTITION BY ItemNo ORDER BY DateOfTest) as FutureDateOfTest
FROM test_results
)
SELECT
ItemNo
,DateOfTest
,NatureOfTumour
,CASE
WHEN FutureNature = 'IN'
AND FutureLocation = Location
THEN 'Yes'
ELSE 'NO'
END AS State_Change
,FutureDateOfTest - DateOfTest as Date_Diff
,Location
,Centre
from abc
WHERE NatureOfTumour = 'DC'
You need a self join. Something along these lines:
SELECT
d.ItemNo,
i.DateOfTest - d.DateOfTest AS datediff,
d.Location,
d.Centre,
d.Gen
FROM
(
SELECT
*
FROM demo
WHERE NatureOfTumour = 'DC'
) d
INNER JOIN
(
SELECT
*
FROM demo
WHERE NatureOfTumour = 'IN'
) i ON d.ItemNo = i.ItemNo
AND d.Location = i.Location;
If I understood your question, you could try this:
Let me know .
If you want in output only the rows who changed (GEN='Y'), change LEFT JOIN to INNER JOIN.
SELECT A.ITEMNO, A.DATEOFTEST, A.NATUREOFTUMOUR, A.LOCATION
, CASE WHEN B.NATUREOFTUMOUR='IN' AND A.LOCATION = B.LOCATION THEN 'Y' ELSE 'N' END AS GEN_NEW
, CASE WHEN B.NATUREOFTUMOUR='IN' AND A.LOCATION = B.LOCATION THEN B.DATEOFTEST-A.DATEOFTEST END AS TIME_PASS
FROM TE A
LEFT JOIN TE B ON A.ITEMNO=B.ITEMNO AND B.NATUREOFTUMOUR<>'DC' AND A.DATEOFTEST < B.DATEOFTEST
WHERE A.NATUREOFTUMOUR='DC
OR (I can't understand from your question)
SELECT A.ITEMNO, A.DATEOFTEST, A.NATUREOFTUMOUR, A.LOCATION
, CASE WHEN B.NATUREOFTUMOUR='IN' THEN 'Y' ELSE 'N' END AS GEN_NEW
, CASE WHEN B.NATUREOFTUMOUR='IN' THEN B.DATEOFTEST-A.DATEOFTEST END AS TIME_PASS
FROM TE A
LEFT JOIN TE B ON A.ITEMNO=B.ITEMNO AND B.NATUREOFTUMOUR<>'DC' AND A.DATEOFTEST < B.DATEOFTEST AND A.LOCATION = B.LOCATION
WHERE A.NATUREOFTUMOUR='DC'\\
Output
ITEMNO DATEOFTEST NATUREOFTUMOUR LOCATION GEN_NEW TIME_PASS
1 2345 01.07.2006 DC P Y 153
2 2342 01.06.2006 DC Q N NULL
3 5597 01.10.2001 DC P N NULL
4 3878 01.05.2005 DC Q N NULL
5 3878 01.06.2006 DC P N NULL

SQL Query including pivot

I have done a query which include the left outer join and the pivot.
However I keep getting a bugs saying incorrect column.
SELECT * FROM
(select Max(datetimestamp)as datetimestamp, currentSet, tGroup_id from tPhos_Line_Operator
group by currentSet, tGroup_id)T
LEFT OUTER JOIN
(SELECT PO.tGroup_id AS G_ID, PO.CurrentSet AS cr,gP.tTest_id AS Header,convert(float,Po.Results) as Results from tPhos_Line_Operator PO
inner join tPhos_Line_Parameter pp
on PO.tPhos_Line_Parameter_id = PP.id
INNER JOIN tGroup_Parameter GP
on pp.tGroup_Parameter_id = gp.id
where PP.tPhosline_id=134)P
on T.tGroup_id = P.G_ID
AND T.CurrentSet = p.cr
PIVOT ( MAX(p.Results) For Header IN ([4],[23],[24])) AS pvt
Anyone know how to get the DateTimeStamp and the pivot record?
Which mean i will only have 4 columns in this case.
Currently i need to select * from.
I'm sorry still a junior in query.
Thanks in advance.
sample data could go here:
sample of expected result:
dateTime | currentset | tGroup_id | G_ID | cr | 4 | 23 | 24 |
2015-03-11 07:00:24.313 1 69 69 1 8.36 10 14.4
2015-03-12 00:31:58.257 2 69 69 2 9.12 8 14.4
I am making a guess. It appears that you want to "pivot" some results so you get to see these side by side instead of across multiple rows.
While PIVOT has been added into many SQL implementations, it is not the only way to achieve pivoted data nor is it always the best or easiest way to do it. Here is an old fashioned "pivot" that uses a set of case expressions and 'GROUP BY':
SELECT
PO.tGroup_id AS G_ID
, PO.CurrentSet AS cr
, MAX( datetimestamp ) AS datetimestamp
, MAX( CASE WHEN gP.tTest_id = 4 THEN CONVERT(float, Po.Results) END ) AS Results4
, MAX( CASE WHEN gP.tTest_id = 23 THEN CONVERT(float, Po.Results) END ) AS Results23
, MAX( CASE WHEN gP.tTest_id = 24 THEN CONVERT(float, Po.Results) END ) AS Results24
FROM tPhos_Line_Operator PO
INNER JOIN tPhos_Line_Parameter pp ON PO.tPhos_Line_Parameter_id = PP.id
INNER JOIN tGroup_Parameter GP ON pp.tGroup_Parameter_id = gp.id
WHERE PP.tPhosline_id = 134
GROUP BY
PO.currentSet
, PO.tGroup_id
Because you haven't supplied sample data I don't know the details but hopefully you can bend this to suit your data.
This is an alternative approach using the PIVOT operator but this also relies on using MAX() OVER(). One complication for using the PIVOT operator here is that you require a maximum datetime value as well as pivoted rows which is complex using the inbuilt pivot operator. I believe that complexity can be overcome by the MaxDateTime column seen below:
SELECT
MaxDateTime , CR, G_ID, [4], [23], [24]
FROM (
SELECT
PO.tGroup_id AS G_ID
, PO.CurrentSet AS cr
, gP.tTest_id AS Header
, MAX( PO.datetimestamp ) OVER (PARTITION BY PO.tGroup_id, PO.CurrentSet, gP.tTest_id) AS MaxDateTime
, CONVERT( float, Po.Results ) AS Results
FROM tPhos_Line_Operator PO
INNER JOIN tPhos_Line_Parameter pp ON PO.tPhos_Line_Parameter_id = PP.id
INNER JOIN tGroup_Parameter GP ON pp.tGroup_Parameter_id = gp.id
WHERE PP.tPhosline_id = 134
) AS sourve_tbl
PIVOT (MAX( Results ) FOR Header IN ([4], [23], [24])
) AS pvt_tbl
;
Yes your existing query is wrong.
I hv tried to correct it.
;With CTE as
(
select Max(datetimestamp)as datetimestamp, currentSet, tGroup_id
from tPhos_Line_Operator
group by currentSet, tGroup_id
)
Select * from
( SELECT PO.tGroup_id AS G_ID, PO.CurrentSet AS cr,gP.tTest_id AS Header
,convert(float,Po.Results) as Results
,T.*
from tPhos_Line_Operator PO
inner join tPhos_Line_Parameter pp
on PO.tPhos_Line_Parameter_id = PP.id
INNER JOIN tGroup_Parameter GP
on pp.tGroup_Parameter_id = gp.id
left join CTE T on T.tGroup_id = P.PO.tGroup_id
AND T.CurrentSet = PO.CurrentSet
where PP.tPhosline_id=134)tbl
PIVOT ( MAX(p.Results) For Header IN ([4],[23],[24])) AS pvt