SQL Server parameters and percentage increase - sql

How would one use a parameter to increase orders on the orderdetails table by 10 percent?
I did something like: add parameter named IncPercent to the value of an order if the value of IncPercent is under 10%, or if IncPercent is 10% or over, add 10% to the value of an order for all orders in the
OrderDetails table utilising IF/ELSE.*/
Code that I have so far I'm kinda stuck
Create procedure [spAddPercentage]
#incPercent decimal(5,4)
as
update OrderDetails
set #incPercent = #incpercent * 1.10
.........
I cannot figure out how to use the if else statement in this code. Can anyone give me a better understanding or give me a example on what I should add for if/else?

Using an IF/ELSE here seems like a more complicated way to accomplish this. A case expression would be much simpler.
update OrderDetails
set Value = Value * (1 + case when #incPercent < .1 then .1 else #incPercent end)

Here is info on using IF ELSE
https://msdn.microsoft.com/en-gb/library/ms182717.aspx

Related

Selecting a table field and subtracting a CASE with a SUM function

I'm writing a SQL Command for Crystal Reports and I'm still new to SQL, so I'm having trouble with the following scenario. I've got a SUM function to add up the costs of a production job to get me the actual costs. I want to formulate the margin from the invoice amount and subtract the actual cost from this SUM function to populate another field in my report. When the related invoice has a return applied, it shows as a credit memo type rather than a typical invoice. I want to add a CASE function to the Margin SQL statement.
I'm getting this CASE statement to work to get my actual costs:
,(CASE WHEN t1.[Type] = 'CM' THEN '0.00' ELSE (SELECT SUM(Act_Labor+Act_Material+Act_Service+Act_Labor_Burden+Act_Machine_Burden+Act_GA_Burden) FROM Job WHERE Top_Lvl_Job = t0.Job) END)as Act_Cost
I want to incorporate this CASE statement into my formula to get my Margin as seen below:
,(SELECT ISNULL(t0.Amount, 0) - SUM(Act_Labor+Act_Material+Act_Service+Act_Labor_Burden+Act_Machine_Burden+Act_GA_Burden) FROM Job WHERE Top_Lvl_Job = t0.Job) as Margin
I keep getting errors if I try to use the CASE statement in my Margin formula. I'm not sure where I'm going wrong with the sequence or if my syntax has multiple errors.
I've tried the following syntax, but keep getting errors:
,(SELECT ISNULL(t0.Amount,0) - (CASE WHEN t1.[Type] = 'CM' THEN '0.00' ELSE (SUM(Act_Labor+Act_Material+Act_Service+Act_Labor_Burden+Act_Machine_Burden+Act_GA_Burden) FROM Job WHERE Top_Lvl_Job = t0.Job) END))as Margin
So i figured out the answer to my problem. I changed the CASE statement to give me the information i need, but in a different way.
Rather than starting with the SELECT function to pull the invoice amount then use the CASE function, I changed the query to use the CASE function to populate the invoice amount since that was going to populate anyways based on my subtraction.
Here is the statement I'm using that is working now:
,(CASE WHEN t1.[Type] = 'CM' THEN ISNULL(t0.Amount, 0) ELSE (SELECT ISNULL(t0.Amount, 0) - SUM(Act_Labor+Act_Material+Act_Service+Act_Labor_Burden+Act_Machine_Burden+Act_GA_Burden) FROM Job WHERE Top_Lvl_Job = t0.Job)END) as Margin

Failed UPDATE with CASE

I'm trying to write a query which will update reorder_level based on how much of an item was sold within a particular time period.
with a as (select invoice_itemized.itemnum, inventory.itemname,
sum(invoice_itemized.quantity) as sold
from invoice_itemized
join inventory on invoice_itemized.itemnum=inventory.itemnum and
inventory.vendor_number='COR' and inventory.dept_id='cigs'
join invoice_totals on
invoice_itemized.invoice_number=invoice_totals.invoice_number and
invoice_totals.datetime>=dateadd(month,-1,getdate())
group by invoice_itemized.itemnum, inventory.itemname)
update inventory
set reorder_level = case when a.sold/numpervencase>=5 then 30
when a.sold/numpervencase>=2 then 20
when a.sold/numpervencase>=1 then 5
else 1 end,
reorder_quantity = 1
from a
join inventory_vendors on a.itemnum=inventory_vendors.itemnum
Replacing the update with a select performs entirely as expected, returning proper results from the case and selecting 94 rows.
with the update in place, all of the areas affected by the update (6758) got set to 1.
Run this, and eyeball the results:
with a as (select invoice_itemized.itemnum, inventory.itemname,
sum(invoice_itemized.quantity) as sold
from invoice_itemized
join inventory on invoice_itemized.itemnum=inventory.itemnum and
inventory.vendor_number='COR' and inventory.dept_id='cigs'
join invoice_totals on
invoice_itemized.invoice_number=invoice_totals.invoice_number and
invoice_totals.datetime>=dateadd(month,-1,getdate())
group by invoice_itemized.itemnum, inventory.itemname)
select a.sold, numpervencase, a.sold/numpervencase,
case
when a.sold/numpervencase>=5 then 30
when a.sold/numpervencase>=2 then 20
when a.sold/numpervencase>=1 then 5
else 1
end,
*
from a
join inventory_vendors on a.itemnum=inventory_vendors.itemnum
Always a good idea to select before update to check that data ends up as you expect
all of the areas affected by the update got set to 1
I put the raw ingredients into the query above; see if the sums worked out as expected. You might need to cast one of the operands to something with decimal places:
1/2 = 0
1.0/2 = 0.5
And it updated far more rows than i was expecting
Every row that comes out of that select will be updated. Identify the rows you don't want to update and put a where clause in to remove them
Am i overthinking this?
Undertesting, probably
Do I even need the cte?
Makes it easier to represent, but no- you could get the same result by pasting the contents of the cte in as a subquery.. it's what the db does (effectively) anyway
Do i have my from statement in the wrong place?
We don't know what result you're after so that one is impossible to answe beyond "doing so would probably generate a syntax error, so.. no"
The actual problem seems to be
your case when is always going to ELSE, find out why
your cte selects too many rows (I couldn't tell if the number you posted was the number you got or the number you were expecting but it's pretty moot without example data), find out why
Solved. When I added another join to the update it worked correctly. i had to add join inventory on inventory_vendors.itemnum=inventory.itemnum

SQL: Conditional Percentage Increase

Using Bartender custom SQL, I am attempting to add 20% to a label price if it is VAT applicable (i.e. if it has a tax ID of 2583)
The information for tax is stored in one database table called StockItem.TaxCodeID, and the price is stored in another called StockItemPrice.Price.
Is there a way to make this happen? I'm very new to SQL and have gotten by so far using the query and join tools included with bartender, and the code it generates makes logical sense to me.
SELECT "dbo"."StockItem"."Code", "dbo"."StockItem"."Name", "dbo"."StockItem"."TaxCodeID", "dbo"."StockItem"."PartNumber", "StockItemPrice"."Price" FROM "dbo"."StockItem" , "StockItemPrice"
WHERE "dbo"."StockItem"."ItemID" = "StockItemPrice"."ItemID"
AND
("StockItemPrice"."PriceBandID" = 1001
AND "dbo"."StockItem"."Code" LIKE '6%'
AND "dbo"."StockItem"."PartNumber" LIKE '%?BarcodeSearch1%'
AND "dbo"."StockItem"."Name" LIKE '%?NameSearch%'
AND "dbo"."StockItem"."TaxCodeID" = 258
Sorry in advance if I haven't provided enough information, I'll do my best to add more if needed!
Use case when statement,
select *, CASE taxid
WHEN taxid=2538 THEN price *1.20
else price
END as newcolumn
from stockitem

How to accurately figure percentage of a finite total

I’m in the process of creating a report that will tell end users what percentage of a gridview (the total number of records is a finite number) has been completed in a given month. I have a gridview with records that I’ve imported and users have to go into each record and update a couple of fields. I’m attempting to create a report tell me what percentage of the grand total of records was completed in a given month. All I need is the percentage. The grand total is (for this example) is 2000.
I’m not sure if the actual gridview information/code is needed here but if it does, let me know and I’ll add it.
The problem is that I have been able to calculate the percentage total but when its displayed the percentage total is repeated for every single line in the table. I’m scratching my head on how to make this result appear only once.
Right now here’s what I have for my SQL code (I use nvarchar because we import from many non windows systems and get all sorts of extra characters and added spaces to our information):
Declare #DateCount nvarchar(max);
Declare #DivNumber decimal(5,1);
SET #DivNumber = (.01 * 2541);
SET #DateCount = (SELECT (Count(date_record_entered) FROM dbo.tablename WHERE date_record_entered IS NOT NULL and date_record_entered >= 20131201 AND date_record_entered <= 20131231);
SELECT CAST(ROUND(#DivNumber / #DateCount, 1) AS decimal(5,1) FROM dbo.tablename
Let’s say for this example the total number of records in the date_record_entered for the month of December is 500.
I’ve tried the smaller pieces of code separately with no success. This is the most recent thing I’ve tried.
I know I'm missing something simple here but I'm not sure what.
::edit::
What I'm looking for as the expected result of my query is to have a percentage represented of records modified in a given month. If 500 records were done that would be 25%. I just want to have the 25 (and trainling decimal(s) when it applies) showing once and not 25 showing for every row in this table.
The following query should provide what you are looking for:
Declare #DivNumber decimal(5,1);
SET #DivNumber = (.01 * 2541);
SELECT
CAST(ROUND(#DivNumber / Count(date_record_entered), 1) AS decimal(5,1))
FROM dbo.tablename
WHERE date_record_entered IS NOT NULL
and date_record_entered >= 20131201
AND date_record_entered <= 20131231
Why do you select the constant value cast(round(#divNumber / #DateCount, 1) as decimal(5,1)from the table? That's the cause of your problem.
I'm not too familiar with sql server, but you might try to just select without a from clause.
select emp.Natinality_Id,mstn.Title as Nationality,count(emp.Employee_Id) as Employee_Count,
count(emp.Employee_Id)* 100.0 /nullif(sum(count(*)) over(),0) as Nationality_Percentage
FROM Employee as emp
left join Mst_Natinality as mstn on mstn.Natinality_Id = emp.Natinality_Id
where
emp.Is_Deleted='false'
group by emp.Natinality_Id,mstn.Title

Round up prices to end with 99p

My table name is products and i am trying to update products_price so all prices have 99p at the end. Can you help?
Also this request is a bit simpler (i'm new to SQL!) I want to update all records as follows
anything in categories where parent_id is >0 I need the script to update all records to zero.
Q1
So, you want all prices to be truncated and then add 0.99 currency units. The function to truncate a value to 0 decimal places varies between DBMS; I'm assuming it is called TRUNC, but it might be called FLOOR or something else in your DBMS:
UPDATE Products
SET Products_Price = TRUNC(Products_Price) + 0.99;
You don't need a WHERE clause here. I'm assuming there are no negative prices; if that's a possibility, then you need to be a little cleverer with your assignment (maybe a CASE expression; maybe you have a function SIGN, SIGN, SIGNUM available).
Note that I'm assuming that the p referenced is pence, as in 'pounds (Sterling) and pence'. If the price was between £0.00 and £0.99, the result will be £0.99; if the price was between £1.00 and £1.99, the result will be £1.99; etc. The TRUNC or FLOOR will remove any fractional part from the price, and the addition of 0.99 then means that the result is of the form £x.99 for (non-negative) integer values of x.
Q2
Making some assumptions about what you meant:
UPDATE Categories
SET Anything = 0
WHERE Anything > 0
AND Parent_ID > 0;
If you meant that you want to update the products table in some way, then you need to be a lot more precise in your question.
Q2 revisited
From a comment:
I want to update all parent_id values in my categories table to zero where parent_id > 0.
Presumably, there must be some parent_id values which are null or negative, so you need:
UPDATE Categories
SET Parent_ID = 0
WHERE Parent_ID > 0
If there are no nulls and no negatives, then you can run an even simpler update:
UPDATE Categories
SET Parent_ID = 0
It will set to zero those rows which already have a parent ID of zero as well as those that do not. This might hit the logs a bit harder than the more selective update (as in, there will be more changes to record in the logical log or equivalent for your DBMS), but unless there are vast numbers of records and most of them already have a zero parent ID and the DBMS does not recognize when a record does not change and writes log records for unchanged rows, then you're unlikely to notice the difference
Set price to have 99p at end:
update products_price set price = floor(price)+0.99;
Set parent_id to 0:
update categories set parent_id = 0 where parent_id > 0;