The error is 'Operation must use an updatable query'.
I am trying to update the 'orders' table with the information below, however only the price of 1 item will be provided through a text box and I am trying to calculate the total order value using the quantity ordered, which will already be in this table.
The code below includes the data taken from the variables. With the 2 in 'VAT = 2' and 'price = 2' being the price of one single unit (£2.00). The total order value will be stored within the 'price' field and the VAT should be calculated using the same code, but times by 0.2 to give the 20% VAT.
UPDATE orders
SET Invoice_number = 'IN9999',
delivery_note_number = 'DN6000',
price =2 *
(SELECT quantity
FROM orders
WHERE purchase_order_number = 'PO7512'
),
VAT = (2 *
(SELECT quantity
FROM orders
WHERE purchase_order_number = 'PO7512'
)/100) * 20,
shipping = 3
WHERE purchase_order_number = 'PO7512'
Maybe I can't use nested query's this way. I'm not sure, but any help would be appreciated :) Thanks!
Instead of subquerying, you can access the whole record directly in the update, like so:
UPDATE Orders
SET Invoice_number = 'IN9999',
Delivery_note_number = 'DN6000',
Price = 2 * quantity,
VAT = (40 * quantity)/100,
Shipping = 3
WHERE purchase_order_number = 'PO7512'
Note that with fractions it's always better to multiply first and divide later.
Related
I'm fairly new to SQL Server and I'm having trouble implementing a WHERE statement inside a CASE, specifically for a trigger I'm working on.
I have 2 tables with the following fields:
Receipt(ItemID,Quantity)
and
Warehouses(WarehouseID,Stock)
|WarehouseID|Stock|
-------------------
|ARM01 |100 |
|ARM02 |100 |
The trigger checks whether a row with a specific quantity of any given item was inserted, altered or removed to Receipt and then subtracts or adds to the Stock of the Warehouses table.
So if I add a row with 200 Quantity in Receipt, it will subtract 100 from the Stock of WarehouseID 'ARM01', and if there is no Stock left in 'ARM01' (which there isn't because there is only 100), it will subtract the other 100 from 'ARM02'. Of course if 'ARM02' has a Stock of 0 it will print an error but I'll worry about that later.
The thing is, SQL Server doesn't accept a WHERE inside a CASE, because, of course, the entire CASE is already part of the SET statement and WHEREs only come after a SET. It's weird but I couldn't find an answer online yet for such a simple thing.
My goal:
CASE 1
UPDATE 'Stock of Table' where 'WarehouseID of Same Table' = 'ARM01'
CASE 2
UPDATE 'Stock of Table' where 'WarehouseID of Same Table' = 'ARM02'
I also realize the calculus for Stock -/+ Quantity and vice-versa might be wrong right now and I also have 2 statements in parenthesis after a THEN, separated by a AND because I was trying to distribute the first 100 to ARM01 and the rest to ARM02. That's probably very, very misguided and apologies for the incorrect code but for now I just want to figure out where to use a WHERE statement.
CREATE TRIGGER SubtractStock ON Receipt
FOR INSERT, UPDATE, DELETE
AS
[snipped UPDATE for deleted because it only exchanges '+' for '-' in the operation]
UPDATE Warehouses
SET Stock =
(CASE
WHEN inserted.Quantity <= Stock THEN Stock - Quantity WHERE WarehouseID = 'ARM01'
WHEN inserted.Quantity > Stock THEN (Stock - Quantity WHERE WarehouseID = 'ARM01')
AND (Quantity - Stock WHERE WarehouseID = 'ARM02')
END)
FROM inserted JOIN Warehouses ON inserted.ItemID = Warehouses.ItemID
Thank you!
I hate triggers, and this is a bad idea for one. With that out of the way.
For ARM01, move the WHERE to the WHEN with an AND:
SET Stock =
(CASE
WHEN inserted.Quantity <= Stock AND WarehouseID = 'ARM01'
THEN Stock - Quantity
...
The next problem is you need to see two rows to set the stock for ARM02, what the stock is in ARM02 to see if you need to subtract from ARM02, and the stock in ARM02 to subtract from. So moving the condition in the where somewhere else won't help. Probably two update statements, update ARM01, with an output clause to temp table or table valued variable to give before stock values for ARM01, then use that to update the values for ARM02.
Again, this sort of complicated logic rarely is appropriate inside a trigger.
Please try like this...Use proper aliases..
CREATE TRIGGER SubtractStock ON Receipt
FOR INSERT, UPDATE, DELETE
AS
UPDATE W
SET Stock = CASE
WHEN WarehouseID = 'ARM01' AND I.Quantity <= Stock THEN Stock - Quantity
WHEN WarehouseID = 'ARM01' AND I.Quantity > Stock THEN Stock - Quantity
WHEN WarehouseID = 'ARM02' THEN I.Quantity - Stock
END
FROM inserted I JOIN Warehouses W ON I.ItemID = W.ItemID
In Access SQL, I am attempting what should seem like a simple task in attaining a percentage of total. There are 3 item stores (Sears, kmart & Mktpl) of which in any given week, I wish to calculate their respective percent of total based on balance of sales (all can be obtained using one table - tbl_BUChannelReporting).
For example week 5 dummy numbers - Sears 7000, kmart 2500, mktpl 2000
the following ratios would be returned: sears 61%, kmart 22%, mktpl 17%
I was originally trying to create a sub query and wasn't getting anywhere so I am essentially trying to sum sales on one of the item stores in week 5 divided by the sum of all 3 item store sales in week 5. The following is my query, which is giving me "cannot have aggregate function in expression" error:
SELECT FY, FW, Rept_Chnl, BU_NM, Order_Store, Item_Store, CDBL(
SUM(IIF([item_store]="sears", revenue, IIF([item_store]="kmart", revenue, IIF([item_store]="mktpl", revenue,0)))) /
(SUM(IIF([item_store]="sears",revenue,0)+SUM(IIF([item_store]="kmart",revenue,0)+SUM(IIF([item_store]="mktpl",revenue,0))))))
AS Ratios
FROM tbl_BUChannelReporting
WHERE FY = "2017"
AND FW = 5
GROUP BY FY, FW, Rept_Chnl, BU_NM, Order_Store, item_store
Thanks all in advance for taking the time. This is my 1st post here and I don't consider myself anything but a newbie anxious to learn from the best and see how this turns out.
Take care!
-D
Consider using two derived tables or saved aggregate queries: one that groups on Item_Store and the other that does not include Item_Store in order to sum the total stores' revenue. All other groupings (FY, FW, Rept_Chnl, BU_NM, Order_Store) remain in both and used to join the two. Then in outer query, calculate percentage ratio.
SELECT i.*, CDbl(i.Store_Revenue / a.Store_Revenue) As Ratios
FROM
(SELECT t.FY, t.FW, t.Rept_Chnl, t.BU_NM, t.Order_Store, t.Item_Store,
SUM(t.Revenue) As Store_Revenue
FROM tbl_BUChannelReporting t
WHERE t.FY = '2017' AND t.FW = 5
GROUP BY t.FY, t.FW, t.Rept_Chnl, t.BU_NM, t.Order_Store, t.Item_Store) As i
INNER JOIN
(SELECT t.FY, t.FW, t.Rept_Chnl, t.BU_NM, t.Order_Store
SUM(t.Revenue) As Store_Revenue
FROM tbl_BUChannelReporting t
WHERE t.FY = '2017' AND t.FW = 5
GROUP BY t.FY, t.FW, t.Rept_Chnl, t.BU_NM, t.Order_Store) As a
ON i.FY = a.FY AND i.FW = a.FW AND i.Rept_Chnl = a.Rept_Chnl
AND i.BU_NM = a.BU_NM AND i.Order_Store = a.Order_Store
Or save each above SELECT statement as its own query and reference both below:
SELECT i.*, (i.Store_Revenue / a.Store_Revenue) As Ratios
FROM
Indiv_Item_StoreAggQ As i
INNER JOIN
All_Item_StoreAggQ As a
ON i.FY = a.FY AND i.FW = a.FW AND i.Rept_Chnl = a.Rept_Chnl
AND i.BU_NM = a.BU_NM AND i.Order_Store = a.Order_Store
My manager wants to see what is total values of our suppliers shipments, and what is the total values of their invoices recorded. So he can see the differencies and want from suppliers to unsended invoices.
Here is my code.
It is working on accounting table and shipment detail table.
fis_meblag0 is always little from zero because it is 320 account so I mutiply it -1 for get real value.
sth_tutar is value of shipment, sth_vergi is VAT and so the sum of them is equal to sum of total with VAT.
Now the hard part.
Manager wants to diference between them in a other column and also sort the valuez z to a.
I know I can reuse same subselect for the getting totals but I want to know that can I achieve this without using the same subquery again.
I mean in first subselect I have the total, in last column I only need just the total, can I use total without compute it again?
Regards
select
ch.cari_kod as Carikod,
ch.cari_unvan1 as Unvani,
(select (sum(mf.fis_meblag0) * -1)
from dbo.MUHASEBE_FISLERI mf
where (mf.fis_tarih > '20141231' and mf.fis_tarih < '20150201')
and mf.fis_hesap_kod = ch.cari_kod
and mf.fis_meblag0 < 0) as mtoplam,
(Select sum (sth.sth_tutar + sth.sth_vergi)
from dbo.STOK_HAREKETLERI sth
where (sth.sth_tarih > '20141231' and sth.sth_tarih < '20150201')
and sth.sth_cari_kodu = ch.cari_kod
and sth.sth_normal_iade = 0
and sth.sth_tip = 0) as stoplam
from
dbo.CARI_HESAPLAR ch
where
ch.cari_kod like '320%'
try this query:
select Carikod, Unvani, mtoplam, stoplam, mtoplam - stoplam as Grand_total
from
(
-- your full query here
) T
I'm working on an access database at the moment, where I have multiple fields.
Product Quantity (Entered by User)
Product Price (Retrieved by Database)
Total Price (Product Quantity * Product Price)
Discount
Discount needs to be calculated, however I don't know how to set it to 30% on the condition that TotalPrice is more than 50. It would be useful if the TotalPrice automatically updated if it was more than 50 with the discount too.
Set up a new query that brings in Product Quantity, ProductPrice and TotalPrice. Then, in the Design View of the query, add this field:
Discount: IIF((ProductQuantity * ProductPrice) > 50, 30, 0)
If you're not familiar with IIF statements, the above reads: "If ProductQuantity times ProductPrice is greater than 50, then set Discount = 30, otherwise set Discount = 0"
This will set your discount = 0 if Total Price is less than or equal to 50, so edit that last part if it needs to be something else. Also, I made assumptions on your field names, so you may need to tweak those too, but you get the idea.
If you need Discount to actually reflect 30% of Total Price, then if would look like this:
Discount: IIF((ProductQuantity * ProductPrice) > 50, (ProductQuantity * ProductPrice) * .30, 0)
If this is a data entry screen You can add an After_Update Event to Sandwich Price And Sandwich Quantity
Private Sub SandwichPrice_AfterUpdate()
update_total
End Sub
Private Sub SandwichQuantity_AfterUpdate()
update_total
End Sub
Private Sub update_total()
Dim total AS Double
If IsNull(Me.SandwichPrice) OR IsNull(Me.SandwichQuantity) Then Exit Sub
total = Me.SandwichPrice * Me.SandwichQuantity
SELECT CASE total
CASE 51 to 1000
Me.Discount = 0.3
CASE Else
Me.Discount = 0
END SELECT
Me.TotalPrice = total - (total * Me.Discount)
End Sub
Doing it this way will allow you to add multiple tiers of discount by adding CASE Statements i.e. You could add CASE 10 TO 20 with a new discount and it will apply when TotalPrice is >=10 And <= 20.
This will allow your lookup query to return the correct values from discount. I don't think this should be handled in the lookup query but rather in the data storage itself.
From r In ReceiptLines
Where
r.RECEIPT.RECEIPTDATE >= _reportStartDate
And r.RECEIPT.RECEIPTDATE <= _reportEndDate
Let amount = r.QUANTITY * r.PRICE
Let discount = r.RECEIPTDISCOUNTs.Sum(Function(d) d.DISCOUNT)
where discount > 0
Group By Department = r.ITEMSTYLE.ITEM.CATEGORY.DEPARTMENT.DEPARTMENTNAME
Into Sales = Sum(amount - discount),
Average = Average(amount - discount),
Count = Count()
I am fetching all departments and their sales, average, count from the ReceiptLine, Receipt, ReceiptDiscount tables. The problem i am facing is, if i remove where discount > 0, I am getting null exception. But if I include that, then I only get sales that has discount.
How would I write query that bring all sales less discount (if it has one). Any help is highly appreciated.
This is a common pitfall with LINQ2SQL.
The function SUM in SQL returns null if there are no items in the collection, but the signature of Enumerable.Sum() returns an int. This gives a runtime exception when the SQL query return null where the LINQ2SQL provider expects an integer.
The solution is to cast the result of the sum to a nullable integer and use GetValueOrDefault to convert the null-case to 0.
Replace
Let discount = r.RECEIPTDISCOUNTs.Sum(Function(d) d.DISCOUNT)
with
Let discount = CType(r.RECEIPTDISCOUNTs.Sum(Function(d) d.DISCOUNT), Integer?).GetValueOrDefault(0)
Have you tried:
...
Let amount = r.QUANTITY * r.PRICE
Let nDiscount = r.RECEIPTDISCOUNTs.Sum(Function(d) d.DISCOUNT)
Let discount = IIf(nDiscount == Nothing, 0, nDiscount)
Group By Department = r.ITEMSTYLE.ITEM.CATEGORY.DEPARTMENT.DEPARTMENTNAME
...