Add negative to credited invoices only - sql

I am very new to SQL. I have created a query to pull out the total of purchase invoices we have created and I have Union All to the total of purchase credits we have created. The problem I am having is the credits don't show a minus in front of the amount. When I total the results up, the purchase invoices are adding to the credit instead of taking it away.
Is there a way I can get the credits to show negative and invoices to show positive? Please see my query below.
SELECT
T_PURCHASEINVOICE.C_ID,
T_PURCHASEINVOICE.C_DATE,
T_PURCHASEINVOICE.C_NUMBER,
T_PURCHASEINVOICE.C_NETAMOUNT,
T_PURCHASEINVOICE.C_GROSSAMOUNT,
T_PURCHASEINVOICE.C_TAXAMOUNT,
T_TAXRATE.C_CODE
FROM
T_PURCHASEINVOICE (NOLOCK)
JOIN T_PURCHASEINVOICE_TAXLINE (NOLOCK) ON T_PURCHASEINVOICE.C_ID = T_PURCHASEINVOICE_TAXLINE.C__OWNER_
JOIN T_TAXRATE (NOLOCK) ON T_PURCHASEINVOICE_TAXLINE.C_TAXRATE = T_TAXRATE.C_ID
WHERE
T_TAXRATE.C_CODE = '01'
AND T_PURCHASEINVOICE.C_TAXAMOUNT <> 0
UNION ALL
SELECT
T_PURCHASECREDITNOTE.C_ID,
T_PURCHASECREDITNOTE.C_DATE,
T_PURCHASECREDITNOTE.C_NUMBER,
T_PURCHASECREDITNOTE.C_NETAMOUNT,
T_PURCHASECREDITNOTE.C_GROSSAMOUNT,
T_PURCHASECREDITNOTE.C_TAXAMOUNT,
T_TAXRATE.C_CODE
FROM
T_PURCHASECREDITNOTE (NOLOCK)
JOIN T_PURCHASECREDITNOTE_TAXLINE (NOLOCK) ON T_PURCHASECREDITNOTE.C_ID = T_PURCHASECREDITNOTE_TAXLINE.C__OWNER_
JOIN T_TAXRATE (NOLOCK) ON T_PURCHASECREDITNOTE_TAXLINE.C_TAXRATE = T_TAXRATE.C_ID
WHERE
T_TAXRATE.C_CODE = '01'
This is the result
And this is the result I would like to see
Is this possible?

You just need a case statement in front of the following statement
T_PURCHASEINVOICE.C_NETAMOUNT,
with
case when T_PURCHASECREDITNOTE.C_NUMBER = 'PIN' THEN 1 ELSE -1 END * T_PURCHASEINVOICE.C_NETAMOUNT

Related

MS SQL count values for per row for per id

I'm trying to count incident types per depot. My current query returns the following result set:
I then apply a count query on this set which looks like this:
select middleList.DepotName as depot,
count(middleList.NearMiss) as NearMiss,
count(middleList.Theft) as Theft,
count(middleList.Security) as Security,
count(middleList.LostTimeDisablingInjury) as LostTimeDisablingInjury,
count(middleList.Fire) as Fire,
count(middleList.OccupationalIllness) as OccupationalIllness,
count(middleList.VehicleAccident) as LostTimeDisablingInjury,
count(middleList.Spliiage) as Fire,
count(middleList.PropertyDamage) as OccupationalIllness,
count(middleList.NonConformance) as NonConformance,
count(middleList.Other) as Other
from
(SELECT dbo.IncidentTypes.NearMiss, dbo.IncidentTypes.Theft,
dbo.IncidentTypes.Security, dbo.IncidentTypes.LostTimeDisablingInjury,
dbo.IncidentTypes.Fire, dbo.IncidentTypes.OccupationalIllness,
dbo.IncidentTypes.VehicleAccident, dbo.IncidentTypes.Spliiage,
dbo.IncidentTypes.PropertyDamage, dbo.IncidentTypes.NonConformance,
dbo.IncidentTypes.Other, dbo.Incidents.IncidentTitle, dbo.Depots.DepotName,
dbo.Incidents.IncidentNumber
FROM dbo.Departments INNER JOIN
dbo.Depots ON dbo.Departments.DepotId = dbo.Depots.DepotId
INNER JOIN
dbo.Employees ON dbo.Departments.DepartmentId =
dbo.Employees.DepartmentId INNER JOIN
dbo.IncidentTypes INNER JOIN
dbo.Incidents ON dbo.IncidentTypes.IncidentTypeId =
dbo.Incidents.IncidentTypeId ON dbo.Employees.EmployeeId =
dbo.Incidents.EmployeeId_EmployeeInvolv
Where Incidents.DateCreated = (SELECT MAX (i2.DateCreated) FROM
Incidents as i2 WHERE Incidents.IncidentNumber = i2.IncidentNumber)) as
middleList
group by middleList.DepotName
Which return the following incorrect results:
Please help.
Okay so I found the problem.
It seems like the rows are being counted and not the actual values, thus adding this to the count insured that they were being counted properly:
count(case when middleList.NearMiss <> '0' then 0 end ) as NearMiss
End result being:

How to sum a count of bookings to display total bookings for location and total value for location

I am writing a report that needs to show the number of bookings taken for a location with the total value of those bookings.
How do I sum the bookings column and show only one row for the location, that includes the columns set out in the example of expected data?
Select Statement Below:
SELECT
Locations.Description as LocationsDesc,
Locations.LocationGUID,
Venues.VenueName,
Venues.VenueGUID,
count (Bookings.BookingID) as Bookings,
Departments.DepartmentName,
Departments.DepartmentGUID,
sum(SalesTransactionDetails.NetDetailValue) as NetDetailValue,
sum(SalesTransactionDetails.DetailValue) as DetailValue,
SUM(CASE When Salestransactionlines.itemtype = 1 Then SalesTransactionDetails.NetDetailValue Else 0 End ) as RentalFee,
SUM(CASE When Salestransactionlines.itemtype = 2 Then SalesTransactionDetails.NetDetailValue Else 0 End ) as ExtraFee,
SalesTransactions.SalesTransactionGUID
FROM BookingLinesDetails
INNER JOIN Bookings ON BookingLinesDetails.BookingGUID=Bookings.BookingGUID
INNER JOIN Locations ON BookingLinesDetails.LocationGUID=Locations.LocationGUID
INNER JOIN Venues on Venues.Venueguid = Locations.Venueguid
INNER JOIN SalesTransactionDetails ON BookingLinesDetails.BookingLinesDetailGUID=SalesTransactionDetails.BookingLinesDetailGUID
INNER JOIN SalesTransactionLines ON SalesTransactionDetails.SalesTransactionLineGUID=SalesTransactionLines.SalesTransactionLineGUID
INNER JOIN SalesTransactions ON SalesTransactionLines.SalesTransactionGUID=SalesTransactions.SalesTransactionGUID
INNER JOIN Departments on Departments.DepartmentGUID = Locations.DepartmentGUID
WHERE
BookingLinesDetails.StartDateTime >= dbo.InzDateOnly(#pFromDate) and
BookingLinesDetails.StartDateTime < DateAdd(day,1,dbo.inzDateOnly(#pToDate)) and
Departments.DepartmentGUID in (Select GUID from dbo.InzSplitGUID(#DepartmentID)) and
(#IncludeAllLocationGroupsInVenues <> 0 or (#IncludeAllLocationGroupsInVenues = 0 )) and
Venues.VenueGUID in (Select GUID from dbo.InzSplitGUID(#VenueID)) and
salesTransactions.Status = 1 and -- remove cancelled
salestransactions.receiptonly = 0
GROUP BY
Locations.Description,
Locations.LocationGUID,
Venues.VenueName,
Venues.VenueGUID,
Departments.DepartmentName,
Departments.DepartmentGUID,
SalesTransactions.SalesTransactionGUID
The output is currently:
Desired output is:
LocationsDesc LocationGUID VenueGUID Bookings DepartmentName NetDetailValue DetailValue ExtraFee
Location - Deck Room 348A43F12 7DAD77BE 33 Aquatics Centre 2059.46 2162.5 0
I have attempted several versions of Count and sum. I believe I need to make the query a derived table and then select from that, but am not sure how to go about it, even if that is the answer.
Thank you in advance.

Query Results across 3 tables

I have a need to see a client was billed for a specific item. The tables are as follows Client, Orders, Details. The way they connect is Client to Orders and Orders to Details. (client.acctno = order.acctno, order.orderno = details.orderno)
How can I search all orders and display only those that have not been sold a specific item (sample code with exact table names below). My data keep showing all clients because they weren't sold the items a specific order I want to bunch them all together as ALL ORDERS and compare.
SELECT *
FROM plshared.dbo.client
LEFT OUTER JOIN PL00.dbo.ordhdr ON ordhdr.ACCT_NO = client.ACCT_NO
WHERE NOT EXISTS (SELECT *
FROM pl00.dbo.orddet
WHERE orddet.ORDER_NO = ordhdr.order_no
AND orddet.ITEM_NO = '2017WI')
--GROUP BY client.ACCT_NO
ORDER BY CLIENT.ACCT_NO
The problem is your query is at the order level. You might find it easier to get the clients by doing:
SELECT o.ACCT_NO
FROM PL00.dbo.ordhdr o JOIN
pl00.dbo.orddet od
ON od.ORDER_NO = o.order_no
GROUP BY o.ACCT_NO
HAVING SUM(CASE WHEN od.ITEM_NO = '2017WI' THEN 1 ELSE 0 END) = 0;
ORDER BY o.ACCT_NO;

SQL Using Multiply 3 Times with different ID's

I have tables called Products and ProductsDetails. I want to get something like the price of an order. So let's say I want 5 pairs of "Headphonesv1" ( Comparing with not ID but name, since name could change ), 2 packs of "GumOrbit" and 7 packs of "crisps". Pair of headphonesv1 costs 10$, gum 1$ and crisps 2$. So the answer that I should get is bill ID, Bill date, and TotalCost which is = 66. My question is how do I make multiple calculations? The code that I've been trying with one at least but I get syntax error:
SELECT Products.billID, Products.Date, (ProductsDetails.Price * 5 WHERE ProductsDetails.name LIKE 'Headphonesv1')
FROM Products INNER JOIN ProductsDetails ON Products.billdID = ProductsDetails.billID
Also have tried inserting SELECT inside () but then the values that I get are wrong and creating one more inner join inside doesn't seem promising
I think if you just want to see that total cost for multiple items you can use a aggregate and case expression to get the SUM.
SELECT Products.billID,
Products.Date,
SUM(CASE WHEN ProductsDetails.name LIKE 'Headphonesv1' THEN ProductsDetails.Price * 5
WHEN ProductsDetails.name LIKE 'GumOrbit' THEN ProductsDetails.Price * 2
WHEN ProductsDetails.name LIKE 'crisps' THEN ProductsDetails.Price * 7
END) TotalCost
FROM Products
INNER JOIN ProductsDetails ON Products.billdID = ProductsDetails.billID
GROUP BY Products.billID,
Products.Date
this seems very hard coded to serve much use though
Your previous code has a few synax erros. you are closing your parenthesis in the wrong location, and the FROM ... clause should be before the WHERE ... clause. Change your code to this:
SELECT Products.billID, Products.Date, (ProductsDetails.Price * 5)
FROM Products INNER JOIN ProductsDetails ON Products.billdID = ProductsDetails.billID
WHERE ProductsDetails.name LIKE 'Headphonesv1'
and let me know if it works now.
Edited:
The OP requested how to obtain that information for more than one Product. In that case you could switch the statement to:
SELECT SUM(Cost)
FROM (
SELECT Products.billID, Products.Date,
(ProductsDetails.Price *
(CASE WHEN ProductsDetails.name='Headphonesv1' THEN 5 ELSE
CASE WHEN ProductsDetails.name='GumOrbit' THEN 7 ELSE 0 END
END)
) AS Cost
FROM Products INNER JOIN ProductsDetails ON Products.billdID = ProductsDetails.billID
WHERE (ProductsDetails.name = 'Headphonesv1') OR (ProductsDetails.name = 'GumOrbit')
)
And you can continue to add more products.
You probably have another two tables: cart(cartID int/*,more info*/) and cartItems(cartID int /*FK*/, item varchar(50),qty int) where you add something. Finally,
select sum(pd.price * ci.qty) tot
FROM Products p
INNER JOIN ProductsDetails pd ON p.billdID = pd.billID
inner join cartItems ci on ci.item = pd.name
inner join cart c on c.cartID = ci.cartID
where c.cartID = 123456

Using query results in further procedcures

I'm fairly new to SQL especially PL/SQL, I have a grasp of the basics but what i'm trying to do goes over my head. This is a small part of a larger system but I will focus on 3 tables Sale_Head, Sale_Line and Product. This work is being done in Orcale SQL developer.
http://imgur.com/OrfhM0g,i4pMnTx - Sale Table
http://imgur.com/OrfhM0g,i4pMnTx#1 - Product Table
(Im a newbie so i dont have enough rep to directly post images)
Im attempting to build up some procedures that process pending sales. Sales have a status in the Sale_Head which can either be p(pending), s(shipped), i(in progress), x(cancelled), or b(back orders). The procedure(s) need to find sales with a pending status (i've got that far in my code), then check the products stock levels are above the minimum level enough to complete the sale. If all these conditions are met pending sales become i (in progress) and if there is inadequate stock it comes backordered (b). I have a general idea of how to go about this, but when it comes having to referencing the product table using the foreign from sale_line I get confused.
--create or replace procedure Process_Products is
--begin
select Sale_Head.Sale_Num , Sale_Line.Product_Code as
from Sale_Head
inner join Sale_Line on
Sale_Head.Sale_Num = Sale_Line.SALE_NUM
where Sale_head.Status = 'P';
--if Sale_Line.Product_Code = Product.Product_Code >
--end;
This returns the product codes for orders that have a pending status, but now I need to check their stock levels in the product table and make adjustments.
Please correct me if I am wrong, but if you are saying "for those sales in a pending status where enough inventory exists to fulfill the order, change the status to i (in progress), otherwise not enough inventory exists, so change the status to b (backordered)", then the following should help:
-- This is a useful query to display what you need - debugging, use in cursor, etc
SELECT sh.Sale_Num, sl.Product_Code, sl.Quantity as QtyToBuy,
p.Stock_Count, p.Minimum_Level,
(Case When sl.Quantity <= p.Minimum_Level Then 'i'
Else 'b' end) as NewStatus
FROM Sale_Head sh
INNER JOIN Sale_Line sl
ON sh.Sale_Num = sl.SALE_NUM
INNER JOIN Product p
ON sl.Product_Code
WHERE Sale_head.Status = 'P';
The status code can be updated in one query if that is what you want:
--This query will actully do the update (if view is updatable)
UPDATE
(
SELECT sh.Status, (Case When sl.Quantity <= p.Minimum_Level Then 'i'
Else 'b' end) as NewStatus
FROM Sale_Head sh
INNER JOIN Sale_Line sl
ON sh.Sale_Num = sl.SALE_NUM
INNER JOIN Product p
ON sl.Product_Code
WHERE sh.Status = 'P'
) a
SET a.Status = a.NewStatus;
If the above view is not updatable, try this syntax:
--Otherwise try this syntax
UPDATE Sale_Head sh1 Set Sale_Head.Status =
SELECT (Case When sl.Quantity <= p.Minimum_Level Then 'i'
Else 'b' end) as NewStatus
FROM Sale_Head sh
INNER JOIN Sale_Line sl
ON sh.Sale_Num = sl.SALE_NUM
INNER JOIN Product p
ON sl.Product_Code
WHERE sh1.Sale_Num = sh.Sale_Num
)
WHERE Sale_Head.Status = 'P';