Add or subtract from total using CASE conditions in SQLite - sql

I need a query that subtracts or adds according to a condition for SQLite using the CASE statement. This is my query at the moment:
SELECT s.companyName, CASE ia.type
WHEN ia.type='add' THEN SUM(ia.quantity)
WHEN ia.type='subtract' THEN SUM(-ia.type)
ELSE SUM(0) END AS total
FROM stocktake s
LEFT JOIN stocktake_adjustment sa ON s.stocktakeId = sa.stocktakeId
LEFT JOIN adjustment a ON a.adjustmentId = sa.adjustmentId
LEFT JOIN inventory_adjustment ia ON ia.adjustmentId = a.adjustmentId
LEFT JOIN inventory i ON i.inventoryId = ia.inventoryId
LEFT JOIN supplier s ON s.supplierId = i.supplierId
WHERE s.supplierId = '4da99b63-fcb9-9b9f-8415-4896caeb920c';
Basically I want to add if the condition is 'add' or subtract if condition is subtract, from the total.
Thank you in advance guys.

Move your CASE into SUM:
SELECT s.companyName, SUM(CASE ia.type
WHEN ia.type='add' THEN ia.quantity
WHEN ia.type='subtract' THEN -ia.quantity
ELSE 0
END)
AS total
FROM stocktake s
LEFT JOIN stocktake_adjustment sa ON s.stocktakeId = sa.stocktakeId
LEFT JOIN adjustment a ON a.adjustmentId = sa.adjustmentId
LEFT JOIN inventory_adjustment ia ON ia.adjustmentId = a.adjustmentId
LEFT JOIN inventory i ON i.inventoryId = ia.inventoryId
LEFT JOIN supplier s ON s.supplierId = i.supplierId
WHERE s.supplierId = '4da99b63-fcb9-9b9f-8415-4896caeb920c';
(I assumed that -ia.type in the original question was a typo, really meaning -ia.quantity)

I think what you need is to move the CASE statement inside the SUM, remove ia.type from between CASE and WHEN (or change to a simple CASE statement), and also add GROUP BY:
SELECT s.companyName,
SUM(CASE WHEN ia.type = 'add' THEN ia.Quantity
WHEN ia.type = 'subtract' THEN -ia.Quantity
ELSE 0
END) AS total
FROM stocktake s
LEFT JOIN stocktake_adjustment sa
ON s.stocktakeId = sa.stocktakeId
LEFT JOIN adjustment a
ON a.adjustmentId = sa.adjustmentId
LEFT JOIN inventory_adjustment ia
ON ia.adjustmentId = a.adjustmentId
LEFT JOIN inventory i
ON i.inventoryId = ia.inventoryId
LEFT JOIN supplier s
ON s.supplierId = i.supplierId
WHERE s.supplierId = '4da99b63-fcb9-9b9f-8415-4896caeb920c'
GROUP BY s.CompanyName;

Related

I'm Getting Count of a column same for all rows?How to count occurrences of a column value efficiently in SQL?

Select
Sales_Detail.Serial_No
,Sales_Detail.Tax_Percentage
,Card_Amount
,Cash_Amount
,ISNULL((Select Count(DISTINCT Tax_Percentage) From Sales_Detail
Left Join Sales_Master ON
Sales_Master.Serial_No=Sales_Detail.Serial_No
Where Sales_Master.Invoice_Date = '14-Feb-2019'
And IsSaved='True'And IsCancelled = 'False'
And Card_Amount >0 Or Sales_Master.Cash_Amount>0
And Sales_Detail.Serial_No=10467),1) As Count_Tax
From Sales_Detail
Inner Join Item_Master On Sales_Detail.Item_ID = Item_Master.Item_ID
Inner Join Item_Brand On Item_Master.Brand_ID = Item_Brand.Brand_ID
Inner Join Sales_Master On Sales_Detail.Serial_No=Sales_Master.Serial_No
left Join Customer C on C.Customer_ID =Sales_Master.Customer_ID
Inner Join Tax On Tax.Tax_Percentage=Sales_Detail.Tax_Percentage
Where Sales_Master.Invoice_Date = '14-Feb-2019' And IsSaved = 'True'
And IsCancelled = 'False'
order by Sales_Detail.SGST_Percentage ,Tax_Percentage
While taking count from above query.
I'm getting count as 2 for all row .Why is it so??
If above select in the query expected the output count as 2 for all rows ,
But actually I want to set count as 1 for serial No 10467 and count as 2 for serial No 10468.
Select
Count(DISTINCT Tax_Percentage)
From Sales_Detail
Left Join Sales_Master ON Sales_Master.Serial_No=Sales_Detail.Serial_No
Where Sales_Master.Invoice_Date = '14-Feb-2019'
And IsSaved='True'And IsCancelled = 'False'
And Card_Amount >0 Or Sales_Master.Cash_Amount>0
And Sales_Detail.Serial_No=10467
enter image description here
In your select you are hardcoding the Searial_No And Sales_Detail.Serial_No=10467 so for each row you will get the same value.
Change your like following.
Select
Sales_Detail.Serial_No
,Sales_Detail.Tax_Percentage
,Card_Amount
,Cash_Amount
,ISNULL((Select Count(DISTINCT Tax_Percentage) From Sales_Detail SD
Left Join Sales_Master ON
Sales_Master.Serial_No=SD.Serial_No
Where Sales_Master.Invoice_Date = '14-Feb-2019'
And IsSaved='True'And IsCancelled = 'False'
And Card_Amount >0 Or Sales_Master.Cash_Amount>0
And SD.Serial_No=Sales_Detail.Serial_No
),1) As Count_Tax
From Sales_Detail
Inner Join Item_Master On Sales_Detail.Item_ID = Item_Master.Item_ID
Inner Join Item_Brand On Item_Master.Brand_ID = Item_Brand.Brand_ID
Inner Join Sales_Master On Sales_Detail.Serial_No=Sales_Master.Serial_No
left Join Customer C on C.Customer_ID =Sales_Master.Customer_ID
Inner Join Tax On Tax.Tax_Percentage=Sales_Detail.Tax_Percentage
Where Sales_Master.Invoice_Date = '14-Feb-2019' And IsSaved = 'True'
And IsCancelled = 'False'
order by Sales_Detail.SGST_Percentage ,Tax_Percentage
Suggestion : As a good practice always use alias names for your table so that it can be easily used at multiple places without confusion.

SQL SUM columns from different tables

Good Afternoon,
I currently have the query:
SELECT erp_user.login,
SUM(invoice_header.invoice_amount) as 'Invoices Billed'
FROM erp_user
LEFT JOIN order_header ON erp_user.erp_user_id = order_header.req_by
LEFT JOIN invoice_instruct_header ON order_header.order_id = invoice_instruct_header.order_id
LEFT JOIN invoice_header ON invoice_instruct_header.instruct_id = invoice_header.instruct_no
WHERE erp_user.supervisor_id IS NOT NULL AND user_id_type = 'I' AND erp_user.company_id IS NOT NULL AND erp_user.is_active = 1
GROUP BY erp_user.login
It gives me a list of total billing in our system by employee where the employee is signed to a job on the job header.
I would love to add the total amount of open PO's to this query so I added:
SELECT erp_user.login, SUM(invoice_header.invoice_amount) as 'Invoices Billed', sum(po_header.po_amount) AS "Open PO's"
FROM erp_user
LEFT JOIN order_header ON erp_user.erp_user_id = order_header.req_by
LEFT JOIN invoice_instruct_header ON order_header.order_id = invoice_instruct_header.order_id
LEFT JOIN invoice_header ON invoice_instruct_header.instruct_id = invoice_header.instruct_no
LEFT JOIN po_header ON order_header.order_id = po_header.order_id
WHERE erp_user.supervisor_id IS NOT NULL AND user_id_type = 'I' AND erp_user.company_id IS NOT NULL AND erp_user.is_active = 1 AND po_header.status = 1
GROUP BY erp_user.login
ORDER BY "Open PO's"
That query gives me numbers in my Open PO's column, but they are incorrect and I'm at the point now where I can't figure out how to troubleshoot this.
Can someone please point me in the right direction? I don't mind doing the work, just need a pointer. Thanks!
Please be aware of conbination of Left join and Where clause.
SELECT erp_user.login
, SUM(invoice_header.invoice_amount) as 'Invoices Billed'
, sum(CASE WHEN po_header.status = 1 THEN po_header.po_amount ELSE 0 END) AS "Open PO's"
FROM erp_user
LEFT JOIN order_header ON erp_user.erp_user_id = order_header.req_by
LEFT JOIN invoice_instruct_header ON order_header.order_id = invoice_instruct_header.order_id
LEFT JOIN invoice_header ON invoice_instruct_header.instruct_id = invoice_header.instruct_no
LEFT JOIN po_header ON order_header.order_id = po_header.order_id
WHERE erp_user.supervisor_id IS NOT NULL
AND user_id_type = 'I'
AND erp_user.company_id IS NOT NULL
AND erp_user.is_active = 1
GROUP BY erp_user.login
ORDER BY "Open PO's";
If po_header joins to order_header, then in your original query it would be repeating each po_header for each invoice_header as well (leading to the incorrect calculation).
You could use outer apply() like so:
select
erp_user.login
, [Invoices Billed] = sum(invoice_header.invoice_amount)
, x.[Open POs]
from erp_user
left join order_header
on erp_user.erp_user_id = order_header.req_by
left join invoice_instruct_header
on order_header.order_id = invoice_instruct_header.order_id
left join invoice_header
on invoice_instruct_header.instruct_id = invoice_header.instruct_no
outer apply (
select
[Open POs] = sum(po_header.po_amount)
from po_header p
inner join order_header oh
on oh.order_id = p.order_id
where oh.req_by = erp_user.erp_user_id
) x
where erp_user.supervisor_id is not null
and erp_user.company_id is not null
and erp_user.is_active = 1
and user_id_type = 'I'
group by erp_user.login

SQL Select Query into another query

I am a beginner with SQL so apologise in advance if my terminology / coding is a little off, or maybe way off.
I have two queries which I would like to join into one. The first creating a list of productids which contain two specific processes.
I then want to use these productids in the second query.
Also is below correct?
group by products.productid having (sum(case when processid like 'pick%' then 1 else 0 end) + sum(case when processid like 'pack%' then 1 else 0 end) = 2)
Any help would be much appreciated, hope this makes sense.
SELECT
Products.ProductID
FROM Products
INNER JOIN Categories ON Products.Category = Categories.Category
INNER JOIN Boms ON Products.Product = Boms.Product AND Boms.BomVersion = Products.BomVersion
LEFT OUTER JOIN Products AS Comp ON Boms.Component = Comp.Product
LEFT OUTER JOIN Processes ON Boms.Process = Processes.Process
WHERE
products.active = 1
and Categorys.Categoryid in ('5','20')
group by products.productid
having (sum(case when processid like 'pick%' then 1 else 0 end) + sum(case when processid like 'pack%' then 1 else 0 end) = 2)
order by products.productid
SELECT
Products.ProductID,
Products.productdescription,
Boms.Type As Type,
Comp.ProductId as Component,
Comp.productdescription,
Boms.Quantity,
BomVersions.BomVersionID,
Processes.processid,
Processes.ProcessDescription
FROM Products
INNER JOIN Categories ON Products.Category = Categories.Category
INNER JOIN Boms ON Products.Product = Boms.Product AND Boms.BomVersion = Products.BomVersion
LEFT OUTER JOIN Products AS Comp ON Boms.Component = Comp.Product
LEFT OUTER JOIN Processes ON Boms.Process = Processes.Process
INNER JOIN BomVersions ON Products.BomVersion = BomVersions.BomVersion
WHERE
products.active = 1
order by products.productid, products.type,comp.productid
To combine them you could do the following.
SELECT b.*
FROM
(SELECT Products.ProductID FROM Products INNER JOIN ...) AS a
INNER JOIN
(SELECT Products.ProductID, Products.productdescription, Boms.Type As Type, ...) AS b
ON a.ProductID = b.ProductID

Sum a Single column into multiple columns based on criteria SQL Server

Right now I am collecting a sum of times based on grouping by a part, job, machine, and type.
I would like to have the summed times to be split across multiple columns rather than multiple rows based on the type. How can I do this?
Here is my code
SELECT
m.[machineName]
,pr.[jobNumber]
,p.[partNumber]
,sc.[type]
,SUM(pl.[elapsedTime]) AS elapsedTime
FROM wincc.dbo.productionLog pl
INNER JOIN wincc.dbo.machines m ON pl.[machineId] = m.id
INNER JOIN wincc.dbo.productionRuns pr ON pl.[productionRunId] = pr.id
INNER JOIN wincc.dbo.parts p ON pr.[partId] = p.Id
INNER JOIN wincc.dbo.statusCodes sc ON pl.[statusCodeId] = sc.id
GROUP BY
m.[machineName]
,pr.[jobNumber]
,p.[partNumber]
,sc.[type]
Which produces:
But I want:
Thank you All!
This is a form of table pivoting. Here's one way to do that with conditional aggregation:
SELECT
m.[machineName]
,pr.[jobNumber]
,p.[partNumber]
,SUM(CASE WHEN sc.Type = 'planned downtime' then pl.[elapsedTime] END) AS plannedDT
,SUM(CASE WHEN sc.Type = 'unplanned downtime' then pl.[elapsedTime] END) AS unplannedDT
,SUM(CASE WHEN sc.Type = 'production' then pl.[elapsedTime] END) AS production
,SUM(CASE WHEN sc.Type = 'rework' then pl.[elapsedTime] END) AS rework
FROM wincc.dbo.productionLog pl
INNER JOIN wincc.dbo.machines m ON pl.[machineId] = m.id
INNER JOIN wincc.dbo.productionRuns pr ON pl.[productionRunId] = pr.id
INNER JOIN wincc.dbo.parts p ON pr.[partId] = p.Id
INNER JOIN wincc.dbo.statusCodes sc ON pl.[statusCodeId] = sc.id
GROUP BY
m.[machineName]
,pr.[jobNumber]
,p.[partNumber]

How to add a summary row with totals in MSSQL query?

Here's the Query
SELECT
MAX (Supplier.SupplierName) as Supplier,
MAX (Department.Name) as Department,
MAX (Category.Name) as Category,
MAX (ItemClass.ItemLookupCode) as Matrix,
MAX (Item.ItemLookupCode) as ItemLookupCode,
MAX (Item.Description) as Description,
SUM (TransactionEntry.Quantity) as QtySold,
MAX (Item.Cost) as Cost,
MAX (Item.Price) as Price,
MAX (TransactionEntry.Price) as SoldPrice,
SUM (TransactionEntry.Price * TransactionEntry.Quantity) as TotalSale,
MAX (Item.Quantity) as OnHand
FROM TransactionEntry
INNER JOIN [Transaction] WITH(NOLOCK)
ON TransactionEntry.TransactionNumber = [Transaction].TransactionNumber AND TransactionENtry.ItemType <> 9 AND TransactionEntry.StoreID = [Transaction].StoreID
INNER JOIN Batch WITH(NOLOCK)
ON [Transaction].BatchNumber = Batch.BatchNumber AND [Transaction].StoreID = Batch.StoreID
LEFT JOIN Item WITH(NOLOCK)
ON TransactionEntry.ItemID = Item.ID
LEFT JOIN Department WITH(NOLOCK)
ON Item.DepartmentID = Department.ID
LEFT JOIN Category WITH(NOLOCK)
ON Item.CategoryID = Category.ID
LEFT JOIN Supplier WITH(NOLOCK)
ON Item.SupplierID = Supplier.ID
LEFT JOIN ReasonCode AS ReasonCodeDiscount WITH(NOLOCK)
ON TransactionEntry.DiscountReasonCodeID = ReasonCodeDiscount.ID
LEFT JOIN ReasonCode AS ReasonCodeTaxChange WITH(NOLOCK)
ON TransactionEntry.TaxChangeReasonCodeID = ReasonCodeTaxChange.ID
LEFT JOIN ReasonCode AS ReasonCodeReturn WITH(NOLOCK)
ON TransactionEntry.ReturnReasonCodeID = ReasonCodeReturn.ID
LEFT JOIN Store ON [Transaction].StoreID = Store.ID
LEFT JOIN ItemClassComponent WITH(NOLOCK)
ON Item.ID = ItemClassComponent.ItemID
LEFT JOIN ItemClass WITH(NOLOCK)
ON ItemClassComponent.ItemClassID = ItemClass.ID
WHERE DATEDIFF(week, [Transaction].Time, GETDATE()) = 1 AND
Supplier.SupplierName = 'Name'
GROUP BY Item.ItemLookupCode
Here's the query and how do I add summary row for total numbers for some of the column? I tried several things but could not find anything...
Please help!!!!
http://i29.photobucket.com/albums/c259/xkrntamax/Capture_zps511d8kun.jpg
You are probably looking for grouping sets or with rollup:
Change the group by clause to:
GROUP BY GROUPING SETS ((Item.ItemLookupCode), ())