How to break sales query results by day - sql-server

I have a sales query by date range, where the date range is defined by user input. I would like to divide the results by day. i.e.: say the user input the date range from 01/01/16 - 01/15/16, I would like the break the results for each day.
I'm using DATENAME(DD,T1.[DocDate]) to break it, and it is kind of working, but the results are no accurate. I figure I have to use the same break in the Returns subquery. Please see the full query below:
Thank you
SELECT
'2016' as 'Year',
t4.remarks as 'Department',
DATENAME(DD,T1.[DocDate]) as 'Day',
sum(t0.[quantity])-(ISNULL(p.quantity,0)) as 'Quantity',
sum(t0.linetotal - t0.linetotal*t1.discprcnt/100)-(ISNULL(p.total,0)) as 'Total',
sum(T0.[GrssProfit])-(ISNULL(p.profit,0)) as 'Profit $',
(sum(T0.[GrssProfit])-(ISNULL(p.profit,0)))/(sum(t0.linetotal - t0.linetotal*t1.discprcnt/100)-(ISNULL(p.total,0)))*100 as 'Profit%'
FROM INV1 T0 with (nolock)
INNER JOIN OINV T1 with (nolock) on t0.docentry = t1.docnum
INNER JOIN OSLP T2 with (nolock) on t0.SlpCode = t2.SlpCode
LEFT JOIN OHEM T3 with (nolock) on t0.slpcode = t3.SalesPrson
LEFT JOIN OUDP T4 with (nolock) on t3.dept = t4.Code
--BEGINS QUERY FOR THE RETURNS--
left join (select t9.name as 'dept',sum(t5.quantity) as 'quantity',sum(t5.linetotal - t5.linetotal*t6.discprcnt/100) as 'total',sum(t5.grssprofit) as 'profit'
from [dbo].[rin1] t5 with (nolock)
inner join orin t6 with (nolock) on t5.docentry = t6.docentry
INNER JOIN OSLP T7 with (nolock) on t5.SlpCode = t7.SlpCode
LEFT JOIN OHEM T8 with (nolock) on t5.slpcode = t8.SalesPrson
LEFT JOIN OUDP T9 with (nolock) on t8.dept = t9.Code
INNER JOIN OITM T10 with (nolock) on t5.itemcode = t10.itemcode
where t5.docdate between '[%1]' and '[%2]' and t10.invntitem = 'Y'
and (t5.linetotal - (t5.linetotal*t6.discprcnt/100)) <> '0'
group by t9.name) p on p.dept = t4.name
--ENDS QUERY FOR THE RETURNS--
WHERE t1.docdate between '[%1]' and '[%2]'
and t4.remarks is not null
and t4.remarks = 'perfume provider'
and (t0.linetotal - (t0.linetotal*t1.discprcnt/100)) <> '0'
group by DATENAME(DD,T1.[DocDate]),t4.remarks,p.quantity,p.total,p.profit

Instead of a sub-query for your returns (with the same kind of group by as your Invoices query), you should use a UNION instead. Your Group-By is fine, but like you mentioned, your subquery is going to result in bad data.
Any time you have distinct "starting points" for your data, a Union is the way to go.

Related

SQL JOIN (Result of join is not as expected)

I have these five tables and have an expected outcome for JOIN them.
Example
Table JobShipment
Table Jobheader
Table Branch
Table Company
Table Notetext
My Expected outcome
The outcome is not what I expected.
My query and result
SELECT JS.JS_JobNumber as 'JobNumber', gbb.GB_Code AS 'Branch' , gb.GB_Code as 'Company' ,jh.jh_Dept as 'Dept', ST.ST_NoteText AS 'Note Text'
FROM notetext st (NOLOCK)
LEFT JOIN Company gc (NOLOCK) on st.st_gc_relatedCompany = gc.gc_pk
LEFT JOIN jobshipment js (NOLOCK) ON st.ST_ParentID = js.JS_PK
LEFT JOIN jobheader jh (NOLOCK) on jh.jh_parentID = js.js_pk
left JOIN Branch gbb (NOLOCK) on jh.jh_ge = gbb.GB_PK
left JOIN Branch gb (NOLOCK) ON GB.gb_company = gc.gc_pk AND gbb.gb_pk = gb.gb_pk
where JS.JS_JobNumber = 'S0154'
Why does notetext appear in branch 'CLE'?
I am bad at SQL but gave it a try.
Select jh.jh_parentId as JobNumber,gb.gb_code as Branch,jh.jh_dept as dept, gc.gc_code as Company,st.ST_NoteText as NoteText
from branch gb (NOLOCK)
Inner JOIN Jobheader jh (NOLOCK) on jh.jh_ge=gb.gb_pk
LEFT JOIN Company gc (NOLOCK) on gc.gc_pk=gb.gb_company
Left Join NoteText st (NOLOCK) on st.st_gc_relatedCompany=gb.gb_company
Your JS_JobNumber is related to both companies, so you have to add additional condition that gbb.gb_company = st_gc_relatedCompany
SELECT JS.JS_JobNumber as 'JobNumber', gbb.GB_Code AS 'Branch' , gb.GB_Code as 'Company' ,jh.jh_Dept as 'Dept', ST.ST_NoteText AS 'Note Text'
FROM notetext st (NOLOCK)
LEFT JOIN Company gc (NOLOCK) on st.st_gc_relatedCompany = gc.gc_pk
LEFT JOIN jobshipment js (NOLOCK) ON st.ST_ParentID = js.JS_PK
LEFT JOIN jobheader jh (NOLOCK) on jh.jh_parentID = js.js_pk
left JOIN Branch gbb (NOLOCK) on jh.jh_ge = gbb.GB_PK
left JOIN Branch gb (NOLOCK) ON GB.gb_company = gc.gc_pk AND gbb.gb_pk = gb.gb_pk
where JS.JS_JobNumber = 'S0154' AND gbb.gb_company = st.st_gc_relatedCompany
Apart of that, a little advice to try to be consistant in writing style. You it's really difficult to debug code where the same is written in some places lower case than in other places upper case.
Other thing is that SQL common standard is to write SQL functions and operators in capitals.

What type of SQL join is it in which the inner-join is not directly followed by an ON clause?

What is the name of this type of join? I've looked all over! The query is inner-joining back-to-back and then specifying two ON clauses.
Bonus points: What is the benefit of joining this way?
SELECT
<some columns>
FROM
ProductTypes AS t0
INNER JOIN Table1 AS t1
INNER JOIN Table2 AS t2
ON t2.CodeId = t1.CodeId
AND t2.[Enabled] = 1
ON t1.ClassId = t0.ClassId
Still it will be INNER JOIN.
It will interpreted as
SELECT <some columns>
FROM producttypes AS t0
INNER JOIN table2 AS t2
ON t1.classid = t0.classid
INNER JOIN table1 AS t1
ON t2.codeid = t1.codeid
AND t2.[enabled] = 1
Compiler is smart enough to rearrange the JOIN order
Here is demo of what's happening internally. I have used my own table's with similar JOIN order
Your query JOIN order
SELECT
*
FROM
users AS t0
INNER JOIN products AS t1
INNER JOIN orders AS t2
ON t2.productid = t1.productid
AND t2.productid = 1
ON t2.uid = t0.uid
Execution Plan
The rearranged JOIN order
SELECT
*
FROM
users AS t0
INNER JOIN orders AS t2
ON t2.uid = t0.uid
INNER JOIN products AS t1
ON t2.productid = t1.productid
AND t2.productid = 1
Execution Plan
As you can see both has identical execution plan. So there wont be any difference
This is a form of doing nested joins. There's no purpose with all inner unless you want to do it for readability. It can be useful if you use left outer. Consider:
SELECT
<some columns>
FROM
ProductTypes AS t0
LEFT OUTER JOIN Table1 AS t1
INNER JOIN Table2 AS t2
ON t2.CodeId = t1.CodeId
AND t2.[Enabled] = 1
ON t1.ClassId = t0.ClassId
Now this does something. If you did it without putting the t1/t0 at the end the t1/t2 inner would basically negate the fact that t1/t0 is a left outer. So doing it this way lets you have t0 records with no t1 records (just like a normal left outer join), but will only show the t1 records that ALSO have a t2. The inner join is enforced at this lower level.
See also:
http://sqlity.net/en/1435/a-join-a-day-nested-joins/
SQL join format - nested inner joins

The multi part identifier could not be bound

I am getting this error while running following query
SELECT
T2.[AcctCode],
T2.[AcctName],
T5.[Name],
SUM(T0.[Debit]) AS Actual,
SUM(T3.[DebLTotal]) AS Budget
FROM [dbo].[JDT1] T0
INNER JOIN [dbo].[OJDT] T1
ON T0.[TransId] = T1.[TransId]
INNER JOIN [dbo].[OACT] T2
ON T0.[Account] = T2.[AcctCode],
[dbo].[OBGT] T#
INNER JOIN [dbo].[BGT1] T4
ON T3.[AbsId] = T4.[BudgId]
INNER JOIN OBGS T5
ON T3.[Instance] = T5.[AbsId]
WHERE T2.[AcctName] LIKE '%Travel%'
AND T5.[Name] LIKE 'Main Budget 2015'
GROUP BY T2.[AcctCode], T2.[AcctName], T5.[Name]

SQL Server Nested Query Performance

I need some help writing this query for SQL Server. The nested part makes this query take almost a minute to run on 27,000 records. I think it needs a temp table, but I have not done this before. Can someone give me an idea how I might do this?
SELECT
r.ID,
r.CloseDate,
r.RepairOrderStatus 'Repair Status',
p.PartNumber ModInPN,
p.PartDescription ModInDesc,
pr.RMANumber,
c.FullName OpsTech,
(SELECT COUNT (*)
FROM dbo.TestPartsReplaced tpr
WHERE tpr.RepairID = r.ID) Qty
FROM dbo.RepairTicket r LEFT JOIN dbo.Parts p ON r.ModuleInPartID = p.ID
LEFT JOIN dbo.PartReturn pr ON r.PartReturnID = pr.ID
LEFT JOIN dbo.Contact c ON c.ID = r.ContactTechID
Try this....
SELECT
r.ID,
r.CloseDate,
r.RepairOrderStatus 'Repair Status',
p.PartNumber ModInPN,
p.PartDescription ModInDesc,
pr.RMANumber,
c.FullName OpsTech,
Qty.[Count] AS Quantity
FROM dbo.RepairTicket r LEFT JOIN dbo.Parts p ON r.ModuleInPartID = p.ID
LEFT JOIN dbo.PartReturn pr ON r.PartReturnID = pr.ID
LEFT JOIN dbo.Contact c ON c.ID = r.ContactTechID
LEFT JOIN (SELECT RepairID , COUNT (*) AS [Count]
FROM dbo.TestPartsReplaced
GROUP BY RepairID) Qty ON Qty.RepairID = r.ID

Workaround with 'Column Name is not valid'

Hi is there any workaround with this one?
SELECT invoices.no, customers.name, invoices.mdcode,
SUM(iproducts.unitprice * iproducts.quantity) AS total,
SUM(iproducts.unitprice * iproducts.quantity) - SUM(rinvoices.payment + rinvoices.discount)
AS [Remaining Balance]
FROM invoices INNER JOIN
customers ON customers.id = invoices.customerid INNER JOIN
iproducts ON invoices.id = iproducts.invoiceid LEFT OUTER JOIN
rinvoices ON invoices.id = rinvoices.invoiceid
WHERE ([Remaining Balance] <> '0')
GROUP BY invoices.no, customers.name, invoices.mdcode
The following returns an error that '[Remaining Balance]' is not a valid column whereas i already declared it. i can't use it in both the WHERE and the CASE clauses. Is there any work around since i really need to get only the invoices that have still remaining balances.
Thanks for the help!
You have to use HAVING clause like this
HAVING SUM(rinvoices.payment) - SUM(rinvoices.discount) <> 0
instead of WHERE
Ie:
SELECT invoices.no, customers.name, invoices.mdcode,
SUM(iproducts.unitprice * iproducts.quantity) AS total,
SUM(iproducts.unitprice * iproducts.quantity) - SUM(rinvoices.payment + rinvoices.discount)
AS [Remaining Balance]
FROM invoices INNER JOIN
customers ON customers.id = invoices.customerid INNER JOIN
iproducts ON invoices.id = iproducts.invoiceid LEFT OUTER JOIN
rinvoices ON invoices.id = rinvoices.invoiceid
GROUP BY invoices.no, customers.name, invoices.mdcode
HAVING SUM(rinvoices.payment) - SUM(rinvoices.discount) <> 0

Resources