Using results of JOIN statement to join on the results of another JOIN statement - sql

I have the following 2 Join Statements:
--Get Total Hrs
DECLARE #BeginDate datetime, #EndDate datetime
set #BeginDate = '01-01-2013'
set #EndDate = '12-31-2013'
BEGIN
SELECT F.Type, E.Product, SUM(F.Hours * E.Amount) AS 'Total Hours'
FROM Hours H
INNER JOIN Equipment E
ON F.SN = E.SN
WHERE (F.Date BETWEEN #BeginDate AND #EndDate)
GROUP BY F.Type, E.Product
ORDER BY Product ASC
END
--Get Number of Unscheduled Removals
DECLARE #BeginDate1 datetime, #EndDate1 datetime
set #BeginDate1 = '01-01-2013'
set #EndDate1 = '12-31-2013'
BEGIN
SELECT LEFT(dbo.fn_GetPartName(R.PartID),CHARINDEX('-',dbo.fn_GetPartName(R.PartID), 1) - 1) AS 'Part No',
Count(s.status) AS NumberUnscheduledRemovals
FROM Repair R
INNER JOIN Conversion C
ON R.Performed = C.Performed
AND R.Confirmed = C.Confirmed
INNER JOIN Status S
ON C.StatusID = S.StatusID
WHERE (R.Received BETWEEN #BeginDate1 AND #EndDate1)
AND (S.Status = 'UNSCHEDULED')
GROUP BY LEFT(dbo.fn_GetPartName(R.PartID),CHARINDEX('-',dbo.fn_GetPartName(R.PartID), 1) - 1)
ORDER BY LEFT(dbo.fn_GetPartName(R.PartID),CHARINDEX('-',dbo.fn_GetPartName(R.PartID), 1) - 1) ASC
END
Both queries have results including part numbers (these have the same values). I want to INNER JOIN the results from both queries on the resulting part numbers. have been trying for a while but cant seem to get the syntax right to do it.

Use a temp table using CREATE TABLE #TempPartNum1 & #TempPartNum2.
Grab all the relevant data from the first two queries and put them in the temp tables, then join the temp tables.

You could also use a CTE ("Common Table Expression"):
;WITH QueryOne AS (
... put your first query here
), QueryTwo AS (
... put your second query here
) SELECT blah blah blah
FROM QueryOne INNER JOIN QueryTwo ON foo = bar
CTEs are very handy for things like this.

Related

How to extract people who have NOT transacted since the last visit

I'm supposed to be reaching users who have NOT transacted since the configured days. I'm capturing users who HAVE transacted within X days. Not quite sure how I should get the user who have NOT transacted since the last the visit
CREATE PROCEDURE [ContentPush].[GetLastVisitDateTransaction]
#DaysSinceLastVisit INT,
#TenantID UNIQUEIDENTIFIER
AS
BEGIN
DECLARE #ReturnJson NVARCHAR(MAX)
SET #ReturnJson = (
SELECT DISTINCT [D].[UserID]
FROM [dbo].[UserInfo] D WITH(NOLOCK)
INNER JOIN [Txn].[Txn] T WITH (NOLOCK) ON [D].[UserID]=[T].[UserID]
INNER JOIN [Txn].[TxnPaymentResponse] TPR WITH(NOLOCK) ON [T].[TxnID] = [TPR].[TxnID]
WHERE
[TPR].[PaymentResponseType] = 'FINAL'
AND [TPR].[PaymentResultCode] = 'approved'
AND [T].[AppTenantID] = #TenantID
AND
(
[T].[TransactionDateTime]>= DATEADD(DD, - #DaysSinceLastVisit, GETUTCDATE())
)
AND D.IsActive = 1
FOR JSON PATH)
SELECT #ReturnJson
END
You can start from the users table, and use not exists to filter out those that had a transaction within the period.
SELECT [D].[UserID]
FROM [dbo].[UserInfo] D
WHERE NOT EXISTS (
SELECT 1
FROM [Txn].[Txn] T
INNER JOIN [Txn].[TxnPaymentResponse] TPR ON [T].[TxnID] = [TPR].[TxnID]
WHERE
[D].[UserID]=[T].[UserID]
AND [TPR].[PaymentResponseType] = 'FINAL'
AND [TPR].[PaymentResultCode] = 'approved'
AND [T].[AppTenantID] = #TenantID
AND [T].[TransactionDateTime]>= DATEADD(DD, - #DaysSinceLastVisit, GETUTCDATE())
AND D.IsActive = 1
)

Show totals in last row of query

I would like to show the totals of the last 2 columns but can't seam to get the right code.
Here is the code.
declare #FromDate as datetime
declare #ToDate as datetime
set #FromDate='1/1/2018'
set #ToDate='1/31/2018'
Select
OrderMain.OrderNumber,
OrderMain.OrderDate,
OrderMain.TotalMiles,
OFAddStop.FeeValue AS NumberStops
From
Ordermain with (readuncommitted)
Left Outer Join Customer with (readuncommitted) on Ordermain.CustomerID=Customer.CustomerID
Left outer join OrderFee OFAddStop with (readuncommitted) on OFAddStop.OrderID=OrderMain.OrderID
and OFAddStop.Sequence=9 and OFAddStop.SubSequence=6
Where
Customer.CustomerCode IN('36716')
and OrderMain.OrderDate >=#FromDate
and OrderMain.OrderDate <=#ToDate
and OrderMain.OrderStatus in ('N','A','I','P')
Here is an example of the Query
OrderNumber OrderDate TotalMiles NumberStops
10747511 01/02/18 280 6
10750287 01/03/18 118 4
The last row should look like this
OrderNumber OrderDate TotalMiles NumberStops
10747511 01/02/18 280 6
10750287 01/03/18 118 4
Total 398 10
Can someone show me the correct way to make this happen?
In SQL Server, you can do this using GROUPING SETS, but you need an aggregation query:
Select om.OrderNumber, om.OrderDate,
SUM(om.TotalMiles) as TotalMiles,
SUM(oaf.FeeValue) as NumberStops
From Ordermain om Join
Customer c
on om.CustomerID = c.CustomerID Left outer join
OrderFee oaf
on oaf.OrderID = om.OrderID and
oaf.Sequence = 9 and oaf.SubSequence = 6
Where c.CustomerCode in ('36716') and
om.OrderDate >= #FromDate
om.OrderDate <= #ToDate and
om.OrderStatus in ('P', 'A', 'I', 'N') -- couldn't resist
group by grouping sets ( (om.OrderNumber, om.OrderDate), () );
Notes:
Table aliases make the query easier to write and to read.
The aggregation is on the first two columns. I presume there are no duplicates for those.
You are looking for a specific customer, so the join to that table should be a regular join.
If the db accepts With clause.
declare #FromDate as datetime
declare #ToDate as datetime
set #FromDate='1/1/2018'
set #ToDate='1/31/2018'
With
records as (
Select
cast(OrderMain.OrderNumber as varchar(32)) OrderNumber,
OrderMain.OrderDate,
OrderMain.TotalMiles,
OFAddStop.FeeValue AS NumberStops
From
Ordermain with (readuncommitted)
Left Outer Join Customer with (readuncommitted) on
Ordermain.CustomerID=Customer.CustomerID
Left outer join OrderFee OFAddStop with (readuncommitted) on
OFAddStop.OrderID=OrderMain.OrderID
and OFAddStop.Sequence=9 and OFAddStop.SubSequence=6
Where
Customer.CustomerCode IN('36716')
and OrderMain.OrderDate >=#FromDate
and OrderMain.OrderDate <=#ToDate
and OrderMain.OrderStatus in ('N','A','I','P')
)
Select
OrderNumber,
OrderDate,
TotalMiles,
NumberStops
From
records
Union All
Select
'Total',
null,
sum(TotalMiles),
sum(NumberStops)
From
records

SQL Code working in SSMS but not in Report Builder 3.0

I have a code that works in SSMS but not in Report Builder. Tn the first part I create a temporary table and in the second i attach that table (using join) to my entire query. In SSMS i can do it declaring twice the parameters and using GO after the temporary table is created but RP Builder i cannot use go.
Below you can find the code.
Any hint is appreciated. Thank you!
IF OBJECT_ID('tempdb..#TempResTable') IS NOT NULL DROP TABLE #TempResTable
IF OBJECT_ID('tempdb..#Temp123') IS NOT NULL DROP TABLE #Temp123
declare #fromDate date
set #fromDate='2015-10-26'
declare #toDate date
set #toDate='2015-11-17'
Create table #tempResTable (id_resource int, Mins int)
while (#fromDate <= #toDate)
begin
Insert into #TempResTable
select
r.id_resource
,datediff(mi,coalesce(cw.from_time,convert(time, '12:00:00 AM')),coalesce(cw.till_time,convert(time , '23:59:59 PM'))) as 'MinutesAvailable'
from calendar
join resource r on r.id_calendar=calendar.id_calendar
left join calendarVersion cv on cv.id_calendarVersion=calendar.id_calendar
left join calendarweekdayentry cw on cw.id_calendarVersion=cv.id_calendarVersion
--where r.id_resource=#resource
where cw.id_availabilitykind in(2,8)
and cw.weekday=(case when (datediff(dd,cv.from_date,#fromDate)+1)-((datediff(dd,cv.from_date,#fromDate)+1)/(nofweeks*7)*(nofweeks*7))=0 then nofweeks*7
else (datediff(dd,cv.from_date,#fromDate)+1)-((datediff(dd,cv.from_date,#fromDate)+1)/(nofweeks*7)*(nofweeks*7))
end)
Group By r.id_resource
,cv.from_date
,cw.from_time
,cw.till_time,cw.id_availabilitykind
--)
set #fromDate=dateadd(dd,1,#fromDate)
end
go
declare #fromDate date
set #fromDate='2015-10-26'
declare #toDate date
set #toDate='2015-11-17'
select * into #temp123 from
(
select vwdepartment.departmentName
,row_number() over (order by resource.ID_resource) as 'rowNumber'
,resource.resourceName
,resource.id_resource
,B.AvailabilityHours
--,vwplannedShift.id_shift
--,vwplannedShift.plannedstartinstant
--,vwplannedShift.plannedfinishinstant
--,datediff(mi,vwplannedShift.plannedstartinstant,vwplannedShift.plannedfinishinstant)
, ( select sum(distinct(datediff(mi,vwplannedShift.plannedstartinstant,vwplannedShift.plannedfinishinstant))) from resource r1 where r1.resourceName=resource.resourceName group by r1.resourceName ) as 'MinsPlanned'
--,cw.from_time
--,cw.till_time
--,[dbo].[sp_ResourceAvailability]
from vwplannedShift
join vwshift on vwshift.id_shift = vwplannedShift.id_shift
and datediff(dd,#fromDate , vwplannedShift.plannedStartInstant) >=0
and datediff(dd,#toDate , vwplannedShift.plannedStartInstant) <=0
join vwdepartment on vwdepartment.id_department = vwplannedShift.id_department
join vwaction actions on coalesce(actions.t3_shift, actions.id_shift) = vwshift.id_shift
join vwresourceCombinationDriver driver on actions.id_unionResourceCombi = driver.id_resourceCombination
join resource on driver.id_resource = resource.id_resource
join resourceKind rk on rk.id_resourceKind=resource.id_resourceKind
join calendar c on c.id_calendar=resource.id_calendar
join calendarversion cv on cv.id_calendar=c.id_calendar
join calendarweekdayentry cw on cw.id_calendarVersion=cv.id_calendarVersion
left join availabilityKind ak on ak.id_availabilityKind=cw.id_availabilityKind and cw.id_availabilityKind in (2,8)
LEFT JOIN (select id_resource, sum(mins)AS AvailabilityHours from #tempResTable GROUP BY #tempResTable.id_resource) B ON B.ID_RESOURCE=RESOURCE.ID_RESOURCE
group by resource.resourcename,resource.id_resource,vwdepartment.departmentName,B.AvailabilityHours
union
select vwdepartment.departmentName
,row_number() over (order by resource.ID_resource) as 'rowNumber'
,resource.resourceName
,resource.id_resource
,B.AvailabilityHours
--,vwplannedShift.id_shift
--,vwplannedShift.plannedstartinstant
--,vwplannedShift.plannedfinishinstant
--,datediff(mi,vwplannedShift.plannedstartinstant,vwplannedShift.plannedfinishinstant)
,( select sum(distinct(datediff(mi,vwplannedShift.plannedstartinstant,vwplannedShift.plannedfinishinstant))) from resource r1 where r1.resourceName=resource.resourceName group by r1.resourceName ) as 'MinsPlanned'
--,cw.from_time
--,cw.till_time
from vwplannedShift
join vwshift on vwshift.id_shift = vwplannedShift.id_shift
and datediff(dd,#fromdate , vwplannedShift.plannedStartInstant) >=0
and datediff(dd,#todate , vwplannedShift.plannedStartInstant) <=0
join vwdepartment on vwdepartment.id_department = vwplannedShift.id_department
join vwaction actions on coalesce(actions.t3_shift, actions.id_shift) = vwshift.id_shift
join vwresourcecombinationtruck truck on actions.id_unionResourceCombi = truck.id_resourceCombination
join resource on truck.id_resource = resource.id_resource
join resourceKind rk on rk.id_resourceKind=resource.id_resourceKind
left join calendar c on c.id_calendar=resource.id_calendar
left join calendarversion cv on cv.id_calendar=c.id_calendar
left join calendarweekdayentry cw on cw.id_calendarVersion=cv.id_calendarVersion
left join availabilityKind ak on ak.id_availabilityKind=cw.id_availabilityKind and cw.id_availabilityKind in (2,8)
LEFT JOIN (select id_resource, sum(mins)AS AvailabilityHours from #tempResTable GROUP BY #tempResTable.id_resource) B ON B.ID_RESOURCE=RESOURCE.ID_RESOURCE
group by resource.resourcename,resource.id_resource,vwdepartment.departmentName,B.AvailabilityHours
) as cte
select* from #temp123
Quoting from the documentation on GO:
GO is not a Transact-SQL statement; it is a command recognized by the sqlcmd and osql utilities and SQL Server Management Studio Code editor.
So not recognized by Report Builder.
While TT has identified the problem with the code you have, the workaround would be to create a new Stored Procedure in the database, which will allow you to create, populate and interrogate temporary tables at will.
Something like this perhaps?
CREATE PROCEDURE [dbo].[GetMyData] ( #startDate DATETIME, #endDate DATEIME )
Create table #tempResTable (id_resource int, Mins int)
...
(All the rest of your code (without the variable declarations and 'GOs')
...
select* from #temp123
GO
GRANT EXECUTE ON [dbo].[GetMyData] TO [MyUser]
GO
Then reference this directly from your Dataset by choosing "Stored Procedure" instead of "Text"

SQL conundrum - date filter doesn't work

Really scratching my head here. I have a query that has a date filter. However, I keep getting results that lie outside my date filter period! I have checked that my column is indeed a date column, I have tried using Between and >= <= and none of these seem to have the slightest impact.
Here is an example of my code.
Declare #PARAM_REPORTING_START_DATE as datetime
Declare #PARAM_REPORTING_END_DATE as datetime
Declare #PARAM_CRDTR_ID as integer
Set #PARAM_REPORTING_START_DATE = '2015/06/12'-- 05:39:44 AM'
Set #PARAM_REPORTING_END_DATE = '2015/06/24'-- 05:39:44 AM'
Set #PARAM_CRDTR_ID = 1005
--select #PARAM_REPORTING_START_DATE, #PARAM_REPORTING_END_DATE
Select distinct
capj.cnsmr_accnt_pymnt_jrnl_id,
c.cnsmr_nm_prfx_txt,
c.cnsmr_nm_frst_txt,
c.cnsmr_nm_lst_txt,
capj.cnsmr_accnt_pymnt_pstd_dt,
isdate(capj.cnsmr_accnt_pymnt_pstd_dt) as is_date,
capj.bckt_trnsctn_typ_cd as capj_bckt_trnsctn_typ_cd ,
pm.pymnt_memo_nm
from
cnsmr_accnt_pymnt_jrnl capj
inner join cnsmr_pymnt_jrnl cpj
on capj.cnsmr_pymnt_jrnl_id = cpj.cnsmr_pymnt_jrnl_id
inner join pymnt_memo pm
on pm.pymnt_memo_id = cpj.pymnt_memo_id
inner join crdtr cr
on capj.crdtr_id = cr.crdtr_id
inner join cnsmr_accnt ca
on ca.cnsmr_accnt_id = capj.cnsmr_accnt_id
inner join cnsmr c on c.cnsmr_id = ca.cnsmr_id
Where
capj.cnsmr_accnt_pymnt_pstd_dt>=#PARAM_REPORTING_START_DATE
and
capj.cnsmr_accnt_pymnt_pstd_dt<=#PARAM_REPORTING_END_DATE
and
( -1 IN ( #PARAM_CRDTR_ID ) ) OR ( cr.crdtr_ID in (#PARAM_CRDTR_ID) )
There is a misplacement of braces
Where
capj.cnsmr_accnt_pymnt_pstd_dt>=#PARAM_REPORTING_START_DATE
and
capj.cnsmr_accnt_pymnt_pstd_dt<=#PARAM_REPORTING_END_DATE
and
( -1 IN ( #PARAM_CRDTR_ID ) OR cr.crdtr_ID in (#PARAM_CRDTR_ID) )
You will get all results that satisfy
OR ( cr.crdtr_ID in (#PARAM_CRDTR_ID) )
so the date filter doesn't matter.
You should rearrange the the brackets/braces in your WHERE clause, e.g.
WHERE
capj.cnsmr_accnt_pymnt_pstd_dt
BETWEEN #PARAM_REPORTING_START_DATE AND #PARAM_REPORTING_END_DATE
AND
(
#PARAM_CRDTR_ID = -1
OR
#PARAM_CRDTR_ID = cr.crdtr_ID
);

Slow TSQL query with nested selects

I have written a query, but appears to run quite slowly in our live environment.
The query contains nested select statements which I believe to slow down execution.
Does anyone have any tips of how I could re-write the query to improve the execution speed.
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SET #StartDate = '20140101'
SET #EndDate = '20140101'
SELECT a.applicationid,
a.ourreference,
(SELECT MAX(e.CreateDateTime) FROM tblEmail AS e WHERE( e.ApplicationID = a.ApplicationID) AND (ISNULL(e.StandardEmailID,0) <> 3)) AS 'LastEmail',
(SELECT MAX(l.CreateDateTime) FROM tblLetter AS l WHERE l.ApplicationID = a.ApplicationID AND l.ExternalDocumentTypeID IS NULL) AS 'LastInternalLetter',
(SELECT MAX(l.CreateDateTime) FROM tblLetter AS l WHERE l.ApplicationID = a.ApplicationID AND l.ExternalDocumentTypeID IS NOT NULL) AS 'LastExternalLetter'
INTO #Temp
FROM tblapplication AS a
WHERE (a.LogDate BETWEEN #StartDate AND #EndDate + '23:59:59')
AND (a.BusinessSourceID NOT IN (11, 16))
AND (a.ApplicationStatusID = 100)
SELECT *
FROM #Temp AS tem
WHERE ((LastEmail < LastExternalLetter) AND (LastInternalLetter < LastExternalLetter))
Cheers everyone
edit- Sorry I should say what the query is for. I am trying to see if our customers have sent us a letter and we haven't responded to them with a letter/email
select *
from
(
Select a.applicationId, a.ourreference,
max(e.CreateDateTime) LastEmail,
max(li.CreateDateTime) LastInternalLetter,
max(le.CreateDateTime) LastExternalLetter
from tblApplication a
left outer join tblEmail e on e.ApplicationID = a.ApplicationID
left outer join tblLetter li on li.ApplicationId = a.ApplicationId
left outer join tblLetter le on le.ApplicationId = a.ApplicationId
WHERE (a.LogDate BETWEEN #StartDate AND #EndDate + '23:59:59')
AND (a.BusinessSourceID NOT IN (11, 16))
AND (a.ApplicationStatusID = 100)
and (e.StandardEmailID <> 3 or e.StandardEmailId is null)
group by a.ApplicationId, a.OurReference
)x
WHERE ((LastEmail < LastExternalLetter) AND (LastInternalLetter < LastExternalLetter))
This gets rid of the temporary table. Remember, with SQL wherever you have a Table you can substitute a query (in Selects anyway). This should make it a bit more efficient, but you want to look at the Query Plans and see what's holding it up.
Cheers -