SQL Server where clause order count > 0 - sql

I have a query that works but returns all students, whether they place orders or not. I just want those with orders. The query works fine until I add the where clause. How can I properly write this?
SELECT top 100 percent s.id, s.fname as [First Name], s.lname as [Last Name],
(select count(student_id) from orderX x where x.student_id=s.id) as [Order Count],
(select sum(no_attendees) from orderX x where x.student_id=s.id) as [Attendees / Participants],
(select sum(eventHours) from orderX x where x.student_id=s.id) as [Event Hours],
oc1.text as [Occupation 1], oc2.text as [Occupation 2],
oc3.text as [Occupation 3], s.OccupationOther, s.dateGraduated, s.organization, s.city, s.zip, s.st, s.county,
aud.text as [Preferred Audience], pts.text as [Plans to Share], mr.text as [Main Reason]
FROM student s
left join occupation1 oc1 on s.Occupation1 = oc1.id
left join occupation2 oc2 on s.Occupation2 = oc2.id
left join occupation3 oc3 on s.Occupation3 = oc3.id
left join audience aud on s.audience = aud.id
left join PlanToShare pts on s.PlanToShare = pts.id
left join mainReason mr on s.mainReason = mr.id
where [Order Count] > 0

For starters you could replace your where clause by
where (select count(student_id) from orderX x where x.student_id=s.id) > 0

I think no correlation needed here. Find all the aggregates in subquery and "inner" join it (inner because you are anyways going to filter out zero count rows)
select top 100 percent s.id,
s.fname as [First Name],
s.lname as [Last Name],
x.order_count as [Order Count],
x.attendess_participants as [Attendees / Participants],
x.eventHours as [Event Hours],
oc1.text as [Occupation 1],
oc2.text as [Occupation 2],
oc3.text as [Occupation 3],
s.OccupationOther,
s.dateGraduated,
s.organization,
s.city,
s.zip,
s.st,
s.county,
aud.text as [Preferred Audience],
pts.text as [Plans to Share],
mr.text as [Main Reason]
from student s
left join occupation1 oc1 on s.Occupation1 = oc1.id
left join occupation1 oc2 on s.Occupation2 = oc2.id
left join occupation1 oc3 on s.Occupation3 = oc3.id
left join audience aud on s.audience = aud.id
left join PlanToShare pts on s.PlanToShare = pts.id
left join mainReason mr on s.mainReason = mr.id
inner join (
select student_id,
count(*) as order_count,
sum(no_attendees) as attendess_participants,
sum(eventHours) as event_hours
from orderX x
group by student_id
) x on x.student_id = s.id;

You will have to use
where (select count(student_id) from orderX x where x.student_id=s.id)
instead. In sql-server you cannot use aliases in where clauses.

You cannot use a column alias ([Order count]) in the WHERE clause. Either repeat the
(select count(student_id) from orderX x where x.student_id=s.id)
in the WHERE clause as
WHERE (select count(student_id) from orderX x where x.student_id=s.id) > 0
or use a cte.

Related

Only display the day with the max profit per store

Only display the day with the max profit per store in SQL Server
For example only {Monday 5929.00 DARIEN BRONX GOODS} should only show for DARIEN BRONX GOODS
What I have so far.
select
Dim_Date.WeekDayName,
sum(dbo.DIM_PRODUCT.PRODUCT_PRICE) as [Total Profit],
DIM_D_STORE.STORE_NAME as [Store Name]
from
dbo.DIM_EMPLOYEE
inner join dbo.S_ORDER_FACT on
dbo.DIM_EMPLOYEE.EMPLOYEE_ID = dbo.S_ORDER_FACT.ORDER_EMPLOYEEID
inner join dbo.DIM_CUSTOMER on
dbo.DIM_CUSTOMER.CUSTOMERID = dbo.S_ORDER_FACT.ORDER_CUSTOMERID
inner join dbo.Dim_Date on
dbo.Dim_Date.DateKey = dbo.S_ORDER_FACT.ORDER_DATEID
inner join dbo.DIM_D_STORE on
dbo.DIM_D_STORE.STOREID = dbo.S_ORDER_FACT.ORDER_STOREID
inner join dbo.DIM_PRODUCT on
dbo.DIM_PRODUCT.PRODUCTID = dbo.S_ORDER_FACT.ORDER_PRODUCTID
group by
DIM_D_STORE.STORE_NAME,
Dim_Date.WeekDayName
order by
DIM_D_STORE.STORE_NAME,
[Total Profit] desc
offset 0 rows ;
[Output in image ]
here is one way using window functions:
select * from (
select
Dim_Date.WeekDayName,
sum(dbo.DIM_PRODUCT.PRODUCT_PRICE) as [Total Profit],
DIM_D_STORE.STORE_NAME as [Store Name],
rank() over (partition by STORE_NAME order by sum(dbo.DIM_PRODUCT.PRODUCT_PRICE) desc) rn
from
dbo.DIM_EMPLOYEE
inner join dbo.S_ORDER_FACT on
dbo.DIM_EMPLOYEE.EMPLOYEE_ID = dbo.S_ORDER_FACT.ORDER_EMPLOYEEID
inner join dbo.DIM_CUSTOMER on
dbo.DIM_CUSTOMER.CUSTOMERID = dbo.S_ORDER_FACT.ORDER_CUSTOMERID
inner join dbo.Dim_Date on
dbo.Dim_Date.DateKey = dbo.S_ORDER_FACT.ORDER_DATEID
inner join dbo.DIM_D_STORE on
dbo.DIM_D_STORE.STOREID = dbo.S_ORDER_FACT.ORDER_STOREID
inner join dbo.DIM_PRODUCT on
dbo.DIM_PRODUCT.PRODUCTID = dbo.S_ORDER_FACT.ORDER_PRODUCTID
group by
DIM_D_STORE.STORE_NAME,
Dim_Date.WeekDayName
) table where rn = 1
Wouldn't Top 1 do the job for selecting highest profit?
select Top 1,
Dim_Date.WeekDayName,
sum(dbo.DIM_PRODUCT.PRODUCT_PRICE) as [Total Profit],
DIM_D_STORE.STORE_NAME as [Store Name]
from
dbo.DIM_EMPLOYEE
inner join dbo.S_ORDER_FACT on
dbo.DIM_EMPLOYEE.EMPLOYEE_ID = dbo.S_ORDER_FACT.ORDER_EMPLOYEEID
inner join dbo.DIM_CUSTOMER on
dbo.DIM_CUSTOMER.CUSTOMERID = dbo.S_ORDER_FACT.ORDER_CUSTOMERID
inner join dbo.Dim_Date on
dbo.Dim_Date.DateKey = dbo.S_ORDER_FACT.ORDER_DATEID
inner join dbo.DIM_D_STORE on
dbo.DIM_D_STORE.STOREID = dbo.S_ORDER_FACT.ORDER_STOREID
inner join dbo.DIM_PRODUCT on
dbo.DIM_PRODUCT.PRODUCTID = dbo.S_ORDER_FACT.ORDER_PRODUCTID
group by
DIM_D_STORE.STORE_NAME,
Dim_Date.WeekDayName
order by
[Total Profit] desc,
DIM_D_STORE.STORE_NAME

using sql subtotals

I have the following select statement:
SELECT
c.compname AS [Company]
,x.Ressnavn AS [Client]
,a.jobid AS [Job Number]
,a.JobNavn AS [Job Name]
,t.TName [Task Name]
,cu.DayDate AS [Booking Date]
,cu.HrsBooked AS [Scheduled Hours]
,tr.Sale AS [Sales Value]
,(cu.HrsBooked) * (tr.Sale) AS [Total]
FROM job a
INNER JOIN jobplan jp on jp.JobId=a.jobid
INNER JOIN JobDimensions AS z ON z.jobid = a.jobid
INNER JOIN Ress AS x ON x.RessId = z.custid
INNER JOIN JobPrice AS y ON y.JobId = a.Jobid
INNER JOIN task t on t.PlanId = jp.PlanId
INNER JOIN JobPriceactivity AS w ON w.priceId = y.priceId
INNER JOIN taskres tr ON tr.TaskId = t.TaskId
INNER JOIN emp e ON e.EmpId = tr.ResId
INNER JOIN comp c ON e.compid = c.compid
INNER JOIN CapUsed AS cu ON cu.RefId = tr.TaskResId AND cu.RefType=1
INNER JOIN arpaccount AS ar ON e.empname = ar.arpaccname
AND CAST (cu.DayDate AS DATE) BETWEEN #startdate AND #enddate
WHERE c.compid = '107' AND e.EMPID >='2' AND cu.HrsBooked > '0'
GROUP BY
x.Ressnavn
,a.jobid
,a.JobNavn
,t.TName
,cu.DayDate
,cu.HrsBooked
,y.priceid
,tr.Sale
,c.compname
That gives me the following output but I would like to add in a subtotal of the column 'Total' at each change in client.
An example of what I would like to try and get to is highlighted in green on the output screen grab.
Can anyone advise on the best way to do this?
Try using GROUP BY ROLLUP:
SELECT
x.Ressnavn AS [Client],
c.compname AS [Company],
a.jobid AS [Job Number],
a.JobNavn AS [Job Name],
t.TName [Task Name],
cu.DayDate AS [Booking Date],
cu.HrsBooked AS [Scheduled Hours],
tr.Sale AS [Sales Value],
(cu.HrsBooked) * (tr.Sale) AS [Total]
FROM (...)
GROUP BY
x.Ressnavn,
ROLLUP (
c.compname,
a.jobid,
a.JobNavn,
t.TName,
cu.DayDate,
cu.HrsBooked,
y.priceid,
tr.Sale )

Join results of 3 queries

i have 3 worked queries, but i don't know how to combin them in one query.
TABLES :
------------------ -------------------------- -----------------
PIECE MCARTEFIDENT MCARTEFIDLIG
------------------ -------------------------- -----------------
ET_LIBELLE : Store MFC_ETABLISSEMENT : STORE MFL_ETABLISSEMENT
GP_NUMERO : TICKET MFC_VALDISPOTHEO MFL_NBPASSAGEAPRES
------------------- --------------------------
--QUERY 1
select [et_libelle] AS [STORE NAME],COUNT([GP_NUMERO])
FROM PIECE
LEFT OUTER JOIN ETABLISS ET1 ON gp_etablissement=ET1.ET_ETABLISSEMENT
GROUP BY et_libelle
--QUERY 2
SELECT MFC_ETABLISSEMENT as [STORE NAME], COUNT (MFC_VALDISPOTHEO)
FROM MCARTEFIDENT
LEFT OUTER JOIN ETABLISS ET2 ON MFC_ETABLISSEMENT=ET2.ET_ETABLISSEMENT
GROUP BY MFC_ETABLISSEMENT
--QUERY 3
SELECT MFL_ETABLISSEMENT AS [STORE NAME], MFL_NBPASSAGEAPRES
FROM MCARTEFIDLIG
LEFT OUTER JOIN ETABLISS ET3 ON MFL_ETABLISSEMENT=ET3.ET_ETABLISSEMENT
GROUP BY MFL_ETABLISSEMENT
columns should be the result after combine :
[et_libelle] (Query 1),
COUNT([GP_NUMERO]) (Query 1),
COUNT([GP_NUMERO]) (Query 2),
MFL_NBPASSAGEAPRES (Query 3)
you could use your 3 queries as subqiery and join
select a.[STORE NAME], a.count_gp_numero, b.count_mfc_valdispotheo, c.MFL_NBPASSAGEAPRES
from (
select [et_libelle] AS [STORE NAME], COUNT([GP_NUMERO]) count_gp_numero
FROM PIECE
LEFT OUTER JOIN ETABLISS ET1 ON gp_etablissement=ET1.ET_ETABLISSEMENT
GROUP BY et_libelle
) a
left join (
SELECT MFC_ETABLISSEMENT as [STORE NAME], COUNT(MFC_VALDISPOTHEO) b.count_mfc_valdispotheo
FROM MCARTEFIDENT
LEFT OUTER JOIN ETABLISS ET2 ON MFC_ETABLISSEMENT=ET2.ET_ETABLISSEMENT
GROUP BY MFC_ETABLISSEMENT
) b on a.[STORE NAME] = b.[STORE NAME]
left join (
SELECT MFL_ETABLISSEMENT AS [STORE NAME], MFL_NBPASSAGEAPRES
FROM MCARTEFIDLIG
LEFT OUTER JOIN ETABLISS ET3 ON MFL_ETABLISSEMENT=ET3.ET_ETABLISSEMENT
GROUP BY MFL_ETABLISSEMENT
) c on a.[STORE NAME] = c.[STORE NAME]
If I had to speculate, my guess would be that you want:
select e.*,
(select count(*)
from piece p
where p.gp_etablissement = e.et_etablissement
),
(select count(*)
from MCARTEFIDENT mfc
where mfc.MFC_ETABLISSEMENT = e.et_etablissement
),
(select MFL_NBPASSAGEAPRES -- perhaps a `sum()` here???
from MCARTEFIDENT mfl
where mfl.MFL_ETABLISSEMENT = e.et_etablissement
)
from etabliss e;

How can we Group BY a column in SQL with inner join?

I will attach a screenshot, please look at it:
In this I need to get sum of the [LOCAL CURRENCY] according to each each Branch Name
SELECT
BR.BranchName [BRANCH NAME],
PDS.ProductName [CURRENCY],
SUM(FCBD.Quantity) [QUANTITY],
FCBD.BuyingRate [RATE],
SUM(CONVERT(DECIMAL(12, 3), (FCBD.Quantity * FCBD.BuyingRate))) [LOCAL CURRENCY],
0 [TOTAL]
FROM
ALX_FCBuy FCB
INNER JOIN
ALX_FCBuyDetails FCBD ON FCB.FCBuyID = FCBD.FCBuyID
INNER JOIN
ALX_Branches BR ON FCB.BranchID = BR.BranchID
INNER JOIN
ALX_Products PDS ON FCBD.ProductID = PDS.ProductID
GROUP BY
BR.BranchName, FCBD.ProductID, PDS.ProductName, FCBD.BuyingRate
SELECT
BR.BranchName [BRANCH NAME],
PDS.ProductName [CURRENCY],
SUM(FCBD.Quantity) [QUANTITY],
FCBD.BuyingRate [RATE],
SUM(CONVERT(DECIMAL(12, 3), (FCBD.Quantity * FCBD.BuyingRate))) [LOCAL CURRENCY],
SUM(SUM(CONVERT(DECIMAL(12, 3), FCBD.Quantity * FCBD.BuyingRate))) OVER (PARTITION BY BR.BranchName) [TOTAL]
FROM
ALX_FCBuy FCB
INNER JOIN
ALX_FCBuyDetails FCBD ON FCB.FCBuyID = FCBD.FCBuyID
INNER JOIN
ALX_Branches BR ON FCB.BranchID = BR.BranchID
INNER JOIN
ALX_Products PDS ON FCBD.ProductID = PDS.ProductID
GROUP BY
BR.BranchName, FCBD.ProductID, PDS.ProductName, FCBD.BuyingRate
If you need the sum for each branch, then only put that in the SELECT and GROUP BY:
SELECT BR.BranchName [BRANCH NAME],
SUM(CONVERT(DECIMAL(12, 3), FCBD.Quantity * FCBD.BuyingRate)) [LOCAL CURRENCY],
FROM ALX_FCBuy FCB INNER JOIN
ALX_FCBuyDetails FCBD
ON FCB.FCBuyID = FCBD.FCBuyID INNER JOIN
ALX_Branches BR
ON FCB.BranchID = BR.BranchID INNER JOIN
ALX_Products PDS
ON FCBD.ProductID = PDS.ProductID
GROUP BY BR.BranchName;
If you want an additional column in your existing result set, then the calculation would use window functions:
SELECT . . .
SUM(SUM(CONVERT(DECIMAL(12, 3), FCBD.Quantity * FCBD.BuyingRate))) OVER (PARTITION BY BR.BranchName) as Total
. . .

SQL Query Second sum column squaring results

If I run 2 queries separately I get results like this..
select A.ACTNUMST, sum(B.EXTDCOST) as [IV Total]
from GL00105 A
INNER JOIN SEE30303 B on A.ACTINDX = B.IVIVINDX
group by A.ACTNUMST
Results -
Account No IV Total
2101-00-137 2033.60
4101-00-137 83765.86
6101-00-137 301984.23
Second Query
select A.ACTNUMST as [Account No], SUM(C.PERDBLNC) as [GL Total]
from GL00105 A
LEFT JOIN GL10110 C on A.ACTINDX = C.ACTINDX
group by A.ACTNUMST
Results -
Account No GL Total
2101-00-137 2033.60
4101-00-137 83765.86
6101-00-137 302656.23
I want to be able to join both results together to compare but I believe it is repeating the sum for each line in the GL total and then summing it again, it comes out with large numbers like -
select A.ACTNUMST as [Account No], sum(B.EXTDCOST) as [IV Total], SUM(C.PERDBLNC) as [GL Total]
from GL00105 A
INNER JOIN SEE30303 B on A.ACTINDX = B.IVIVINDX
LEFT JOIN GL10110 C on A.ACTINDX = C.ACTINDX
group by A.ACTNUMST
Results -
Account No IV Total GL Total
2101-00-137 2033.60 14235.20
4101-00-137 83765.86 116350696.20
6101-00-137 301984.23 1612897825.84
When it should be
Results -
Account No IV Total GL Total
2101-00-137 2033.60 2033.60
4101-00-137 83765.86 83765.86
6101-00-137 301984.23 302656.23
Please advise how to use the sum function to get the correct results.
Do you want something like this? Please check and comment if this is not what is expected.
Also please rectify any syntax errors.
SELECT T1.[Account No], T1.[IV Total], T2.[GL Total] FROM
(
select A.ACTNUMST as [Account No], sum(B.EXTDCOST) as [IV Total]
from GL00105 A
INNER JOIN SEE30303 B on A.ACTINDX = B.IVIVINDX
group by A.ACTNUMST
) T1
INNER JOIN
(
select A.ACTNUMST as [Account No], SUM(C.PERDBLNC) as [GL Total]
from GL00105 A
LEFT JOIN GL10110 C on A.ACTINDX = C.ACTINDX
group by A.ACTNUMST
) T2
ON T1.[Account No] = T2.[Account No]
Hope this helps
this can be done with the multiple cte also
with IVTotal as
(
select A.ACTNUMST, sum(B.EXTDCOST) as [IV Total]
from GL00105 A
INNER JOIN SEE30303 B
on A.ACTINDX = B.IVIVINDX
group by A.ACTNUMST
),
GLTotal as
(
select A.ACTNUMST as [Account No], SUM(C.PERDBLNC) as [GL Total]
from GL00105 A
LEFT JOIN GL10110 C
on A.ACTINDX = C.ACTINDX
group by A.ACTNUMST
)
select a.*,b.[GL Total]
from IVTotal a ,GLTotal b
where a.ACTNUMST = b.aCTNUMST