I've searched but can't seem to get this exactly where I need it. This is in regards to Microsoft SQL Server.
I'm looking to join two tables, but only pull in data from the second table for the first date following the date in the first table. See code below.
I've got a table that shows emails sent to customers that looks like this:
SELECT
e.Name
,se.SubscriberID
,se.SendID
,c1.Id
,ds.Service_Num
,sub.EmailAddress
,se.EventDate as 'SentDate'
into #temp_billing_emails
FROM
bi_views.dbo.sfdcMC_SentEvent se
left join bi_views.dbo.sfdcmc_job j on j.jobid=se.sendid
left join bi_views.dbo.sfdcMC_Email e on e.id=j.emailid
left join bi_views.dbo.sfdcMC_Subscriber sub on sub.id=se.SubscriberID
left join sfdcprod.dbo.contact c1 on sub.subscriberkey=c1.id
left join bi_views.dbo.DIM_SERVICE_RF ds on c1.id=ds.ContractSignerContactID_bk
WHERE
e.name like '%Past Due%'
From there, I want to see how many days it took the email receiver to make their first payment following the received email. That's where I've got this:
SELECT
e.*
,z.zuora__createddate__c
,z.zuora__status__c
,z.zuora__amount__c
,datediff(dd,e.sentdate,z.Zuora__CreatedDate__c) DaysToPay
FROM
#temp_billing_emails e
left join sfdcprod.dbo.Service__C sc on e.Service_Num = right(sc.name,len(sc.name)-2)
left join sfdcprod.dbo.[zuora__customeraccount__c] a on sc.billing_account__c=a.id
left join sfdcprod.dbo.[zuora__payment__c] z on a.id=z.zuora__billingaccount__c
WHERE
datediff(dd,e.sentdate,z.Zuora__CreatedDate__c)>=0
and z.zuora__status__c not like 'Error'
That gets me all payments the customer has made after they received an email. What I need is just their first payment amount and the days it took following the email.
I tried the MIN() function like this:
SELECT TOP 100
e.EmailAddress
,e.SentDate
,e.Service_Num
,z.zuora__createddate__c
,z.zuora__status__c
,z.zuora__amount__c
,datediff(dd,e.sentdate,min(z.Zuora__CreatedDate__c)) DaysToPay
FROM
#temp_billing_emails e
left join sfdcprod.dbo.Service__C sc on e.Service_Num = right(sc.name,len(sc.name)-2)
left join sfdcprod.dbo.[zuora__customeraccount__c] a on sc.billing_account__c=a.id
left join sfdcprod.dbo.[zuora__payment__c] z on a.id=z.zuora__billingaccount__c
WHERE
datediff(dd,e.sentdate,z.Zuora__CreatedDate__c)>=0
and z.zuora__status__c not like 'Error'
GROUP BY
e.EmailAddress
,e.SentDate
,e.Service_Num
,z.zuora__createddate__c
,z.zuora__status__c
,z.zuora__amount__c
Any help would be GREATLY appreciated.
outer apply() is a good solution for this type of problem.
select e.*
, x.*
, DaysToPay = datediff(day,e.sentdate,x.Zuora__CreatedDate__c)
from #temp_billing_emails e
outer apply (
select top 1
z.zuora__createddate__c
, z.zuora__status__c
, z.zuora__amount__c
from sfdcprod.dbo.Service__C sc
inner join sfdcprod.dbo.[zuora__customeraccount__c] a
on sc.billing_account__c=a.id
and ds.Service_Num = right(sc.name,len(sc.name)-2)
inner join sfdcprod.dbo.[zuora__payment__c] z
on a.id=z.zuora__billingaccount__c
and z.zuora__status__c not like 'Error'
and z.Zuora__CreatedDate__c >= se.EventDate
order by z.Zuora__CreatedDate__c asc
) as x
I think this is how it would look without the temp table:
select
e.Name
, se.SubscriberID
, se.SendID
, c1.Id
, ds.Service_Num
, sub.EmailAddress
, se.EventDate as 'SentDate'
, x.zuora__createddate__c
, x.zuora__status__c
, x.zuora__amount__c
, DaysToPay = datediff(day,se.EventDate,x.Zuora__CreatedDate__c)
from bi_views.dbo.sfdcMC_SentEvent se
inner join bi_views.dbo.sfdcmc_job j on j.jobid=se.sendid
inner join bi_views.dbo.sfdcMC_Email e on e.id=j.emailid and e.name like '%Past Due%'
left join bi_views.dbo.sfdcMC_Subscriber sub on sub.id=se.SubscriberID
left join sfdcprod.dbo.contact c1 on sub.subscriberkey=c1.id
left join bi_views.dbo.DIM_SERVICE_RF ds on c1.id=ds.ContractSignerContactID_bk
outer apply (
select top 1
z.zuora__createddate__c
, z.zuora__status__c
, z.zuora__amount__c
from sfdcprod.dbo.Service__C sc
inner join sfdcprod.dbo.[zuora__customeraccount__c] a
on sc.billing_account__c=a.id
and ds.Service_Num = right(sc.name,len(sc.name)-2)
inner join sfdcprod.dbo.[zuora__payment__c] z
on a.id=z.zuora__billingaccount__c
and z.zuora__status__c not like 'Error'
and z.Zuora__CreatedDate__c >= se.EventDate
order by z.Zuora__CreatedDate__c asc
) as x
Related
SELECT EMPLOYEE.Fname,EMPLOYEE.Lname,
D.Dnumber,
SUM(WORKS_ON.HOURS) AS SUMHOUR
FROM PROJECT
INNER JOIN DEPARTMENT D ON D.Dnumber = PROJECT.Dnum
INNER JOIN EMPLOYEE ON PROJECT.Dnum= EMPLOYEE.Dno
INNER JOIN WORKS_ON ON WORKS_ON.Pno = PROJECT.Pnumber
GROUP BY EMPLOYEE.Fname,EMPLOYEE.Lname, D.Dnumber
I'm writing a code that lists people with the highest SUMHOUR.
Now, I've found who has the biggest sum, but I can't set condition like max(sum()) for displaying them.
This is my output. In this image, people with Dnumber '5' have highest SUMHOUR '150' and I want to display them. What should I do?
One simple approach uses TOP:
SELECT TOP 1 WITH TIES
e.Fname,
e.Lname,
d.Dnumber,
SUM(w.HOURS) AS SUMHOUR
FROM PROJECT p
INNER JOIN DEPARTMENT d
ON d.Dnumber = p.Dnum
INNER JOIN EMPLOYEE e
ON p.Dnum = e.Dno
INNER JOIN WORKS_ON w
ON w.Pno = p.Pnumber
GROUP BY
e.Fname,
e.Lname,
d.Dnumber
ORDER BY
SUMHOUR DESC;
You have puted Dnumber in group by so it returns highest SUMHOUR in each Dnumber.
So sloution is just remove Dnumber from group by then it return highest SUMHOUR only.
I want to get the count of property and building and building is linked with property. Below is the query I tried:
select
PT.PropertyTypeName,
Count(PropertyID) as ProperyCount,
Isnull((Select count(B.BuildingID)
from Building B
join Property P1
on B.PropertyID=P1.PropertyID
where B.PropertyID =P.PropertyID), 0) as BuildingsCount
from Property P
join PropertyType PT
on PT.PropertyTypeID = P.PropertyTypeID
left join AssetToFund AF
on AF.AssetID = P.AssetID
left join Fund F
on F.FundID = AF.FundID
left join Asset A
on A.AssetID = P.AssetID
left join Client C
on C.ClientID = F.ClientID
where C.ClientId=10000001
group by PT.PropertyTypeName,P.PropertyID
I expect values group of type
and I want to group the count with out duplicate of property-type name
sry for bad English.
Try to use the SUM() function on this subquery
Returns the sum of all the values, or only the DISTINCT values, in the expression. SUM can be used with numeric columns only. Null values are ignored.
MSDN
SUM(Select count(B.BuildingID)
from Building B
join Property P1
on B.PropertyID=P1.PropertyID
where B.PropertyID = P.PropertyID)
When you use GROUP BY then it groups data by columns which you've written in GROUP BY statement. You've written :
GROUP BY PT.PropertyTypeName,P.PropertyID`
it means that SQL Engine will get all unique combinations of PropertyTypeName, PropertyID. However, you want just unique PropertyTypeName. So write just this field into GROUP BY statement:
GROUP BY PT.PropertyTypeName
So complete query will look like this:
select
PT.PropertyTypeName,
Count(PropertyID) as ProperyCount,
Isnull((Select count(B.BuildingID)
from Building B
join Property P1
on B.PropertyID=P1.PropertyID
where B.PropertyID =P.PropertyID), 0) as BuildingsCount
from Property P
join PropertyType PT
on PT.PropertyTypeID = P.PropertyTypeID
left join AssetToFund AF
on AF.AssetID = P.AssetID
left join Fund F
on F.FundID = AF.FundID
left join Asset A
on A.AssetID = P.AssetID
left join Client C
on C.ClientID = F.ClientID
where C.ClientId=10000001
group by PT.PropertyTypeName
I need to show Class Wise attendance like this
IN DB i am have separate table (studentattendance) ,which store attendance like this
I Just Need to Show Total students Present Per Class
I try to do Query which give output like this
this is my query
SELECT distinct CM.ClassName ,SB.SubjectName ,(select count(studentattendance.Day1) from studentattendance where day1 = 'P') as Present, convert(varchar(10),AttendanceDate ,126) as AttendancetimeTaken
from studentattendance SA inner join studentmaster SM on SA.StudentID=SM.ID join ProfessorMaster p on SA.ProfessorID =p.Id
join Classmaster CM on SA.ClassID = CM.ID inner join SubjectMaster SB on SA.SubjectID =SB.ID
I need to Group Class Wise . how can I do it
By not having the actual tables, I tried the following modifications, please try it and reply me
SELECT CM.ClassName ,
SB.SubjectName , count(SA.Day1) as Present,
convert(varchar(10),AttendanceDate , 126) as AttendancetimeTaken
from studentattendance SA
inner join studentmaster SM on SA.StudentID=SM.ID
join ProfessorMaster p on SA.ProfessorID =p.Id
join Classmaster CM on SA.ClassID = CM.ID
inner join SubjectMaster SB on SA.SubjectID =SB.ID
where SA.day1 = 'P'
group by CM.ClassName, SB.SubjectName, AttendanceDate
New to the forum, and new to sql for the most part.
I am getting an error message "Error Converting data type varchar to numeric." when i run the following script. It is referring to the supplier_id field.
I am looking to pull all supplier_id with purchases over the time period defined (1 and 2 years), the number of lines purchased, and the total spent.
select supplier_id,
sum(total_spend_last_12) as total_spend_last_12,
sum(total_spend_last_24) as total_spend_last_24,
count(number_lines_purchased_last_12) as number_lines_purchased_last_12,
count(number_lines_purchased_last_24) as number_lines_purchased_last_24
from (
select a.supplier_id,
sum(e.extended_cost) as total_spend_last_12,
count(e.item_id) as number_lines_purchased_last_12,
0 as total_spend_last_24,
0 as number_lines_purchased_last_24
from p21_view_po_hdr as a
inner join p21_view_po_line as b on b.po_no=a.po_no
inner join p21_view_supplier as c on c.supplier_id=a.supplier_id
left outer join p21_view_inventory_receipts_hdr as d on d.po_number=a.supplier_id
inner join p21_view_inventory_receipts_line as e on e.receipt_number=d.receipt_number
where e.date_created>= dateadd(day,-365,getdate()) and a.location_id='af'
group by a.supplier_id
union
select a.supplier_id,
0 as total_spend_last_12,
0 as number_lines_purchased_last_12,
sum(e.extended_cost) as total_spend_last_24,
count(e.item_id) as number_lines_purchased_last_24
from p21_view_po_hdr as a
inner join p21_view_po_line as b on b.po_no=a.po_no
inner join p21_view_supplier as c on c.supplier_id=a.supplier_id
left outer join p21_view_inventory_receipts_hdr as d on d.po_number=a.supplier_id
inner join p21_view_inventory_receipts_line as e on e.receipt_number=d.receipt_number
where e.date_created >= dateadd(day,-720,getdate()) and a.location_id='af'
group by a.supplier_id
)as tbl
group by tbl.supplier_id
I have a query that is working for the most part until I had to add the inner select for "Trainers".
As you can see in the code below, I am trying to get all of the trainers for each of the segment ID's.
I am getting an error on the first inner selects where clause WHERE trn.segmentID = tes.teSegmentID saying that tes.teSegmentID is not defined.
Is there another way to approach this query in order to get the trainers like I am trying to accomplish?
SELECT *,
(SELECT e2.[FirstName] AS trainerFirst,
e2.[LastName] AS trainerLast
FROM BS_Training_Trainers AS trn
LEFT OUTER JOIN
employeeTable AS e2
ON trn.trainerEmpID = e2.EmpID
WHERE trn.segmentID = tes.teSegmentID
FOR XML PATH ('trainer'), TYPE, ELEMENTS, ROOT ('trainers'))
FROM dbo.BS_TrainingEvents AS a
WHERE a.trainingEventID IN (SELECT tes.trainingEventID
FROM dbo.BS_TrainingEvent_Segments AS tes
INNER JOIN
dbo.BS_TrainingEvent_SegmentDetails AS tesd
ON tesd.segmentID = tes.teSegmentID
INNER JOIN
dbo.BS_LocaleCodes AS locale
ON locale.localeID = tesd.localeID
WHERE locale.location = 'Baltimore');
It seems like you're taking the scenic route towards this:
SELECT a.*,
X.[FirstName],
X.[LastName]
FROM dbo.BS_TrainingEvents AS a
LEFT OUTER JOIN (SELECT e2.[FirstName], e2.[LastName], locale.location FROM dbo.BS_TrainingEvent_Segments AS tes
INNER JOIN dbo.BS_Training_Trainers AS trn ON trn.segmentID = tes.teSegmentID
INNER JOIN dbo.BS_TrainingEvent_SegmentDetails AS tesd ON tesd.segmentID = tes.teSegmentID
INNER JOIN dbo.BS_LocaleCodes AS locale ON locale.localeID = tesd.localeID
LEFT OUTER JOIN employeeTable AS e2 ON trn.trainerEmpID = e2.EmpID) AS X ON a.trainingEventID = X.trainingEventID
WHERE X.location = 'Baltimore';
Not sure if I got all those joins right, it was hard to decode from all the nesting you have going on.
If I have guessed table relationships from their names correctly, the only way to solve this is to reference the same filtering condition twice: first, in the XML generation part, and second in the outer level of the query:
with cte as (
select distinct tes.trainingEventID, tes.teSegmentID
from dbo.BS_TrainingEvent_Segments AS tes
INNER JOIN dbo.BS_TrainingEvent_SegmentDetails AS tesd ON tesd.segmentID = tes.teSegmentID
INNER JOIN dbo.BS_LocaleCodes AS locale ON locale.localeID = tesd.localeID
WHERE locale.location = 'Baltimore'
)
SELECT a.*, (
SELECT e2.[FirstName] AS trainerFirst, e2.[LastName] AS trainerLast
FROM BS_Training_Trainers AS trn
LEFT OUTER JOIN employeeTable AS e2 ON trn.trainerEmpID = e2.EmpID
inner join cte c on trn.segmentID = c.teSegmentID
FOR XML PATH ('trainer'), TYPE, ELEMENTS, ROOT ('trainers')
)
FROM dbo.BS_TrainingEvents AS a
where exists (select 0 from cte c where c.testrainingEventID = a.trainingEventID);
It's difficult to tell whether this is completely correct, of course, but I hope you get the idea.
Oh yes, and if you would have an event with multiple Baltimore segments, you will never be able to tell which trainer takes which one. But you can always add more data into XML to resolve this.