Join two SQL Server Queries into one dataset - sql-server

I have a user that wants summed data on a report. I am able to get the correct data using two separate SQL Queries and they are as follows.
SELECT JH.ProjectID, SUM(EstProdHours) AS EstProdHrs, SUM(ActProdHours)
AS ActProdHrs
FROM JobOper AS JO INNER JOIN JobHead AS JH ON JO.Company = JH.Company AND
JO.JobNum = JH.JobNum WHERE JH.ProjectID <> ''
GROUP BY JH.ProjectID ORDER BY JH.ProjectID
SELECT JH.ProjectID, SUM(EstProdHours) + SUM(EstSetHours) AS Earned
FROM JobOper AS JO INNER JOIN JobHead AS JH ON JO.Company = JH.Company AND
JO.JobNum = JH.JobNum WHERE JH.ProjectID <> '' AND OpComplete = 1
GROUP BY JH.ProjectID ORDER BY JH.ProjectID
This two individual queries deliver the correct data on their own. My goal however, is to setup a SQL view with the results of these two queries together with result as shown below:
ProjectID EstProdHrs ActProdHrs Earned
6000 480.00 1640.59 477
6001 621.00 2431.04 619
6002 6687.97 23234.23 6695.47
6003 414.97 4731.47 416.72
6004 208.00 2196.52 206.00
6005 2.00 76.77 NULL <--- This would show up if no completed ops in 2nd select statement
6006 20.83 819.29 18.83
I have tried to inner join the two queries and I can't seem to avoid "incorrect syntax errors". Here is that statement:
SELECT * FROM
(SELECT JH.ProjectID, SUM(EstProdHours) AS EstProdHrs, SUM(ActProdHours) AS
ActProdHrs,'N/A' AS ValueMissingTableB
FROM JobOper AS JO INNER JOIN JobHead AS JH ON JO.Company = JH.Company AND
JO.JobNum = JH.JobNum WHERE JH.ProjectID <> ''
) AS 1
INNER JOIN
(SELECT JH2.ProjectID, SUM(EstProdHours) + SUM(EstSetHours) AS Earned
FROM JobOper AS JO2 INNER JOIN JobHead AS JH2 ON JO2.Company = JH2.Company
AND JO2.JobNum = JH2.JobNum WHERE JH2.ProjectID <> '' AND OpComplete = 1
) AS 2
ON 1.ProjectID = 2.ProjectID
I have also tried UNION and UNION ALL and it fails because the two queries don't have the same amount of records. I am hoping I am making a rookie mistake here and this can be done. Thanks for any insight.

Try this :
WITH A AS (SELECT JH.ProjectID, SUM(EstProdHours) AS EstProdHrs, SUM(ActProdHours) AS
ActProdHrs,'N/A' AS ValueMissingTableB
FROM JobOper AS JO INNER JOIN JobHead AS JH ON JO.Company = JH.Company AND
JO.JobNum = JH.JobNum WHERE JH.ProjectID <> ''
GROUP BY JH.ProjectID ORDER BY JH.ProjectID
),
B AS
(SELECT JH2.ProjectID, SUM(EstProdHours) + SUM(EstSetHours) AS Earned
FROM JobOper AS JO2 INNER JOIN JobHead AS JH2 ON JO2.Company = JH2.Company
AND JO2.JobNum = JH2.JobNum WHERE JH2.ProjectID <> '' AND OpComplete = 1
GROUP BY JH2.ProjectID ORDER BY JH2.ProjectID
)
SELECT * FROM A
JOIN B ON A.ProjectID = B.ProjectID

I don't have your tables to test this but cant you just do a left join;
SELECT A.ProjectID,A.EstProdHrs, A.ActProdHrs, E.Earned
FROM (
SELECT JH.ProjectID, SUM(EstProdHours) AS EstProdHrs, SUM(ActProdHours) AS ActProdHrs
FROM JobOper AS JO INNER JOIN JobHead AS JH ON JO.Company = JH.Company AND
JO.JobNum = JH.JobNum WHERE JH.ProjectID <> ''
GROUP BY JH.ProjectID
) A
LEFT JOIN (
SELECT JH.ProjectID, SUM(EstProdHours) + SUM(EstSetHours) AS Earned
FROM JobOper AS JO INNER JOIN JobHead AS JH ON JO.Company = JH.Company AND
JO.JobNum = JH.JobNum WHERE JH.ProjectID <> '' AND OpComplete = 1
GROUP BY JH.ProjectID
) E
ON A.ProjectID=E.ProjectID
ORDER BY A.ProjectID

Related

Msg 102, Level 15, State 1, Line 18 Incorrect syntax near ','

Is doesn't seem to like the first comma after SUM(c.[chargeable weight]). Do you guys can identify why? I genuinely can't understand the reason why it is doing this.
Select
(SUM(c.[Chargeable Weight]), MAX (ts.systemstamp), mm.MovementRef
FROM dbo.whsConsignment wc
INNER JOIN dbo.cgtConsignment c ON c.[Consignment Reference] = wc.ConsignmentReference
INNER JOIN dbo.tsAdditionalColInfo ts on ts.[ConsignmentReference]= wc.ConsignmentReference
inner join dbo.movConLink m on m.ConsignmentReference = c.[Consignment Reference]
inner join dbo.movMovement mm on mm.MovementID = m.MovementID
--AND wc.whsHeaderID = wh.WhsHeaderID
AND wc.StatusCode = 'NL'
AND c.[Service Type] = 'C'
--AND ts.SlackNoSlack like 'No Slack - Must Load%'
--and ts.SLackNoSLack like 'No Slack - Tripped%'
and ts.scheduledescription = 'No Slack - Tripped'
group by mm.MovementRef) as chargeableweight
--and ts.systemstamp = max (ts.systemstamp)
Into #2chargns
You missed the SELECT within the brackets
SELECT * FROM
(SELECT SUM(c.[Chargeable Weight]) AS Sum, MAX (ts.systemstamp) AS Max, mm.MovementRef
FROM dbo.whsConsignment wc
INNER JOIN dbo.cgtConsignment c ON c.[Consignment Reference] = wc.ConsignmentReference
INNER JOIN dbo.tsAdditionalColInfo ts on ts.[ConsignmentReference]= wc.ConsignmentReference
inner join dbo.movConLink m on m.ConsignmentReference = c.[Consignment Reference]
inner join dbo.movMovement mm on mm.MovementID = m.MovementID
--AND wc.whsHeaderID = wh.WhsHeaderID
AND wc.StatusCode = 'NL'
AND c.[Service Type] = 'C'
--AND ts.SlackNoSlack like 'No Slack - Must Load%'
--and ts.SLackNoSLack like 'No Slack - Tripped%'
and ts.scheduledescription = 'No Slack - Tripped'
group by mm.MovementRef) as chargeableweight
--and ts.systemstamp = max (ts.systemstamp)
Into #2chargns

Top N percent Desc and Top M percent Asc

I am trying to get top 5 customertypes and show data for each 5 customer types, The balance (which can be any amount) I show them as "Other Customer Types". my issue is since the rows can be random and not perfectly divisible by a number then there can be repeated values in the top 5 showing up in the "Other" group which overstates the Total sales.
the Data is also being rendered in SSRS
My code using TOP PERCENT:
select final.[description], sum(final.YTDSales$) as YTDSales$
FROM(
select top 25 percent pytd2.[Description], sum(pytd2.YTDSales$) as YTDSales$
FROM(
-- ytd sales
select re.SIC_Desc as [description], sum((ol.NetAmt - ol.WhlOrdDiscAmt) / #exrt) AS YTDSales$
from dbo.order_line_invoice ol
INNER JOIN dbo.Vendor vd ON ol.Cono = vd.Cono AND vd.VendId = ol.VendId
inner join Product_Warehouse pw on ol.ProdId = pw.prodid and ol.WhseId = pw.whseid and ol.cono = pw.cono
inner join Customer c on ol.custId = c.CustId and ol.Cono = c.Cono
left join MDData.dbo.RetailEnvironment re on c.SIC = re.SIC
where ol.InvoiceDate BETWEEN #FStartDate AND #EndDate AND ol.Cono = 1 and ol.VendId IN(#Vendid) and ol.prodcatid NOT LIKE 'GP%'
group by re.SIC_Desc
)PYTD2
group by pytd2.[description]
order by sum(pytd2.YTDSales$) DESC
UNION ALL
select top 75 percent 'Other' as 'description', sum(pytd.YTDSales$) as YTDSales$
FROM(
-- ytd sales
select re.SIC_Desc as [description], sum((ol.NetAmt - ol.WhlOrdDiscAmt) / #exrt) AS YTDSales$
from dbo.order_line_invoice ol
INNER JOIN dbo.Vendor vd ON ol.Cono = vd.Cono AND vd.VendId = ol.VendId
inner join Product_Warehouse pw on ol.ProdId = pw.prodid and ol.WhseId = pw.whseid and ol.cono = pw.cono
inner join Customer c on ol.custId = c.CustId and ol.Cono = c.Cono
left join MDData.dbo.RetailEnvironment re on c.SIC = re.SIC
where ol.InvoiceDate BETWEEN #FStartDate AND #EndDate AND ol.Cono = 1 and ol.VendId IN(#Vendid) and ol.prodcatid NOT LIKE 'GP%'
group by re.SIC_Desc
)PYTD
group by Ppytd.[description]
order by sum(pytd.YTDSales$)
)final
group by final.[Description]
order by sum(final.YTDSales$) DESC
my results:
As you can see the Large Independent and Other has the same figure of $2280.60 in YTDQty since it is being repeated
I was picturing something like this:
with data as (
-- your base query here grouped and summarized by customer type
), rankedData as (
select *, row_number() over (order by YTDSales$ desc) as CustTypeRank
from data
)
select
case when CustTypeRank <= 5 then min("description") else 'Others' end as "description",
sum(YTDSales$) as YTDSales$
from rankedData
group by case when CustTypeRank <= 5 then CustTypeRank else 999 end
order by case when CustTypeRank <= 5 then CustTypeRank else 999 end
I actually used RANK instead which worked great :-
select 0 as rankytd, RANK() OVER(ORDER BY sum(ol.NetAmt - ol.WhlOrdDiscAmt) DESC) as rankpytd, re.sic, ol.VendId, vd.name, re.SIC_Desc As [description], 0 AS YTDQty, sum(ol.Quantity) AS PYTDQty
from dbo.order_line_invoice ol
INNER JOIN dbo.Vendor vd ON ol.Cono = vd.Cono AND vd.VendId = ol.VendId
inner join dbo.Product p on ol.Cono = p.Cono and ol.prodid = p.ProdId and p.ProdCatId in (#pcat)
inner join Product_Warehouse pw on ol.ProdId = pw.prodid and ol.WhseId = pw.whseid and ol.cono = pw.cono
inner join Customer c on ol.custId = c.CustId and ol.Cono = c.Cono
left join MDData.dbo.RetailEnvironment re on c.SIC = re.SIC
where ol.InvoiceDate BETWEEN DATEADD(YEAR, -1,#FStartDate) AND DATEADD(YEAR, -1, #EndDate) and ol.Cono = 1 and ol.VendId IN(#Vendid) and ol.prodcatid NOT LIKE 'GP%'
group by re.sic, ol.VendId, vd.Name, re.SIC_Desc

SQL query to fetch repeat column values within time frame

I have an eCommerce website where I am getting lot of fraud orders.. I'd like to pull out those Order_No.
Here is my query
SELECT
O.Order_No, O.Customer_ID, O.DateOrdered, O.IPAddress,
C.FirstName, C.LastName, CD.nameoncard
FROM
Order_No O
INNER JOIN
CardData CD ON O.card_id = CD.id
INNER JOIN
Customers C ON O.customer_id = C.customer_id
ORDER BY
O.order_no desc
Here's the criteria I want to follow:
If the customer_id repeats more than once in 6hrs
If the IPAddress repeats more than once in 6hrs
If the Lastname is NOT found in Nameoncard
Can someone help please?
can you try this
WITH Tmp (Order_No, Customer_id, DateOrdered, IPAddress, FirstName, LastName, NameOnCard)
AS
(
SELECT Ord.Order_No, Ord.Customer_Id, Ord.DateOrdered, Ord.IPAddress,
Cust.FirstName, Cust.LastName, CustData.NameOnCard
FROM Order_No Ord
INNER JOIN Customers Cust
ON
Cust.Customer_Id = Ord.Customer_Id
INNER JOIN
CardData CustData
ON CustData.Id = Ord.Card_Id
)
SELECT DISTINCT a.*
FROM Tmp a
INNER JOIN Tmp b
ON a.Order_No <> b.Order_No
AND a.Customer_Id = b.Customer_Id
WHERE DATEDIFF(hour, a.DateOrdered, b.DateOrdered) >= 6
UNION
SELECT DISTINCT c.*
FROM Tmp c
INNER JOIN Tmp d
ON c.Order_No <> d.Order_No
AND c.IPAddress = d.IPAddress
WHERE DATEDIFF(hour, c.DateOrdered, d.DateOrdered) >= 6
UNION
SELECT DISTINCT e.*
FROM Tmp e
WHERE ISNULL(e.NameOnCard,'') = ''
here is the query:
select * from
(
select b.order_no,b.dateordered,a.customer_id, C.FirstName, C.LastName, cd.nameoncard from order_no as a
left join order_no as b on a.customer_id=b.customer_id
inner join carddata as cd on b.customer_id=cd.customer_id
INNER JOIN Customers C ON b.customer_id = C.customer_id
where a.order_no < b.order_no
and datediff(hour,a.dateordered,b.dateordered) between 0 and 6
union
select b.order_no,b.dateordered,a.customer_id, C.FirstName, C.LastName, cd.nameoncard from order_no as a
left join order_no as b on a.IPAddress=b.IPAddress
inner join carddata as cd on b.customer_id=cd.customer_id
INNER JOIN Customers C ON b.customer_id = C.customer_id
where a.order_no < b.order_no
and datediff(hour,a.dateordered,b.dateordered) between 0 and 6
union
select a.order_no,a.dateordered,a.customer_id, C.FirstName, C.LastName, cd.nameoncard from order_no as a
inner join carddata as cd on a.customer_id=cd.customer_id
INNER JOIN Customers C ON a.customer_id = C.customer_id
where charindex(C.LastName,cd.nameoncard) = 0
) as abc

How to use Having instead of where SQL SERVER

i'm writing query to find the number of student who got marks between 1-50 and 50-70 and 70-100
i tried to solve it but all i did is retrieve the student who got marks between 1-50 just
i need to retrieve the other values (between 50-70 and 70-100)
;with StudentMarks as
(
SELECT Users.UserID,classes.Name Class, courses.Name AS Course, Sum(UserExams.StudentMark) Tot
FROM ClassCourses INNER JOIN classes ON ClassCourses.ClassID = classes.ClassID
INNER JOIN courses ON ClassCourses.CourseID = courses.CourseID
INNER JOIN Exams ON ClassCourses.ClassID = Exams.ClassID AND ClassCourses.CourseID = Exams.CourseID
INNER JOIN SectionsClasses ON classes.ClassID = SectionsClasses.ClassID
INNER JOIN UserExams ON Exams.ExamID = UserExams.ExamID
INNER JOIN Users ON SectionsClasses.SectionID = Users.SectionID AND SectionsClasses.ClassID = Users.ClassID AND UserExams.UserID = Users.UserID
Group by Users.UserID, classes.Name ,courses.Name
)
SELECT Class,Course,
count(UserID)'1-50'
from StudentMarks
where tot between 1 and 50
Group by Class,Course
can anyone help please ?
You can use case
;with studentmarks as (....)
select
class,
course,
case when tot<=49 then '0-49'
when tot>=71 then '71+'
else '50-70' end as gp,
count(userid)
from studentmarks
group by
class,
course,
case when tot<50 then '0-49' when tot>70 then '71+' else '50-70' end
this work nice
select Class,Course,SUM(case when tot between 1 and 50 then 1 else 0 end )'1-50'
,SUM(case when tot between 50 and 70 then 1 else 0 end )'50-70'
,SUM(case when tot between 70 and 100 then 1 else 0 end )'70-100'
FROM
(
SELECT Users.UserID,classes.Name Class, courses.Name AS Course, Sum(UserExams.StudentMark) Tot
FROM ClassCourses INNER JOIN classes ON ClassCourses.ClassID = classes.ClassID
INNER JOIN courses ON ClassCourses.CourseID = courses.CourseID
INNER JOIN Exams ON ClassCourses.ClassID = Exams.ClassID AND ClassCourses.CourseID = Exams.CourseID
INNER JOIN SectionsClasses ON classes.ClassID = SectionsClasses.ClassID
INNER JOIN UserExams ON Exams.ExamID = UserExams.ExamID
INNER JOIN Users ON SectionsClasses.SectionID = Users.SectionID AND SectionsClasses.ClassID = Users.ClassID AND UserExams.UserID = Users.UserID
WHERE courses.CourseID =#pCourseID
Group by Users.UserID, classes.Name ,courses.Name
)AS SQ
GROUP BY Class,Course

multiple count in a sql query

i need a report from a database where i need the final result like
Number of Male, Number of Female, showing against city and finally against State.
I started off with something like.
SELECT p.StateName, d.CityName,
count(api.Gender) as Gender
FROM dbo.Application_Personal_information as api INNER JOIN
dbo.state as p ON api.State = p.ID INNER JOIN
dbo.City as d ON api.City= d.ID
group by p.StateName, d.CityName
when i do this
SELECT p.StateName, d.CityName,
count(api.Gender = 'Male) as Male,
count(api.Gender = 'Female) as Female,
FROM dbo.Application_Personal_information as api INNER JOIN
dbo.state as p ON api.State = p.ID INNER JOIN
dbo.City as d ON api.City= d.ID
group by p.StateName, d.CityName
it give's me error.
incorrect syntax near =.
i also tried with select statement
COUNT(select api.Gender from api where api.Gender ='Male') as Male,
But it is also not working.
...
Any idea?
SELECT
p.StateName, d.CityName,
sum(case when Gender ='Male' then 1 else 0 end ) as Male_count,
sum(case when Gender ='Female' then 1 else 0 end ) as Female_count
FROM
dbo.Application_Personal_information as api INNER JOIN
dbo.state as p ON api.State = p.ID INNER JOIN
dbo.City as d ON api.City= d.ID
group by
p.StateName, d.CityName
You could try the PIVOT function if you are using SQL Server 2005 or later:
WITH CTE AS
( SELECT p.StateName,
d.CityName,
api.Gender
FROM dbo.Application_Personal_information as api
INNER JOIN dbo.state as p
ON api.State = p.ID
INNER JOIN dbo.City as d
ON api.City= d.ID
)
SELECT *
FROM CTE
PIVOT
( COUNT(Gender)
FOR Gender IN ([Male], [Female])
) pvt

Resources