Round up prices to end with 99p - sql

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;

Related

Add new column in SQL based on 2 conditions

I would like to create a new column in SQL using two conditions. I want to create a column that says 1 if the item count is greater than 1 and if item/sum is greater than 5, otherwise return 0. This is not my original data, is there anyway I could add this new column with these specified rows using a select statement.
First I want to say that using SQL key words or SQL function names as table name or column name should be avoided, so if possible, I recommend to rename the columns "number" and "sum".
The second point is it's unclear what should happen in case the sum column is 0. Since a division by zero is not possible, you will need to add a condition for that.
Anyway, the way to achieve such things is using CASE WHEN. So let's add the new column:
ALTER TABLE yourtable ADD column column_name INT;
Now, you need to execute an update command for that column providing the logic you want to apply. As an example, you can do this:
UPDATE yourtable SET column_name =
CASE WHEN item <= 1 THEN 0
WHEN sum = 0 THEN 1
WHEN item / sum > 0.5 THEN 1
ELSE 0 END;
This will set the new column to 1 only in case item is > 1 and sum is 0 or sum item / sum is > 0.5 (greater 50%). In all other cases it will be set to 0. Again, the bad column naming can be seen since "WHEN sum..." looks like you really build a sum and not just use a column.
If you want as example to set the new column to 0 instead of 1 when the sum is 0, just change it and try out.
In case you want to automatically apply this logic fur future inserts or updates, you can add a trigger on your new column. Something like this:
CREATE TRIGGER set_column_name
BEFORE INSERT ON yourtable
FOR EACH ROW
SET new.column_name = CASE WHEN new.item <= 1 THEN 0
WHEN new.sum = 0 THEN 1
WHEN new.item / new.sum > 0.5 THEN 1
ELSE 0 END;
But take care, the syntax of triggers depend on the DB you are using (this example will work in MYSQL). Since you did not tell us which DB you use, you maybe need to modify it. Furthermore, depending on your DB type and your requirements, you need zero, one or two triggers (for updates and for inserts).

How to change 0 to 1 in order to perform arithmetic operations, without UPDATE whole table

I have T1, which is basically price-list, where headers are ITEM_NO; ITEM_NAME; ITEM_PRICE
And table T2 -sold products, which joins T1 using ITEM_Number=ITEM_NO, and headers ITEM_Number, ITEM_TITLE, QTY, PRICE_TOTAL
My aim is to compare the price-list price with the real price paid per 1 item.
Basically, it should compare T2.PRICE_TOTAL/T2.QTY and T1.ITEM_PRICE
However in T2 table are columns where QTY=0 ->, in reality, there should be QTY=1 instead.
So in order to perform DIVIDE operation, I have to change cells 0 to 1.
Thanks
I have tried CASE statement but I think it is not the right tool for this.
CASE
WHEN T2.QTY=0
THEN 1
ELSE T2.QTY
END QTY
It depends on what qty = 0 means.
If it's bad data, skip it.
select price_total/qty
from t2
where qty > 0;
If it means 1, use a case statement to interpret the data.
select
case
when qty=0 then
price_total
else
price_total/qty
end price_per
from t2;
Moving forward, you should fix the data (or convince whomever is allowed to do that to fix it). Then no work around is necessary now nor in the future for you or anybody else. This will avoid unnecessary surprises, bugs, and work.
If 0 means 1, update the table (and find whatever keeps adding 0 sales).
update t2 set QTY = 1 where QTY = 0;
If a quantity of 0 is some special version of quantity 1, add a column to store that special info, set it, and set quantity to 1.
update t2 set qty = 1, special_flag = 'whatever' where qty = 0;
If it's bad data, delete it (and find whatever keeps adding them).
delete from t2 where qty = 0;
If a quantity of 0 is correct and means means 0 then why is there an entry? What does it mean for a quantity of 0 with a non-zero price_total?
The size of the table doesn't matter, run it in the background. Assuming you're using InnoDB tables the update won't lock anything. If you aren't, use update low_priority.

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

What does "<>" mean in Oracle

What does <> mean in SQL language: Sample code is as follows
SELECT ordid,
prodid,
qty
FROM item
WHERE prodid IN (SELECT prodid
FROM item
WHERE ordid = 605)
AND qty IN (SELECT qty
FROM item
WHERE ordid = 605)
AND ordid <> 605;
It means 'not equal to'. So you're filtering out records where ordid is 605. Overall you're looking for any records which have the same prodid and qty values as those assigned to ordid 605, but which are for a different order.
Does not equal. The opposite of =, equivalent to !=.
Also, for everyone's info, this can return a non-zero number of rows. I see the OP has reformatted his question so it's a bit clearer, but as far as I can tell, this finds records where product ID is among those found in order #605, as is quantity, but it's not actually order #605. If order #605 contains 1 apple, 2 bananas and 3 crayons, #604 should match if it contains 2 apples (but not 3 dogs). It just won't match order #605. (And if ordid is unique, then it would find exact duplicates.)
It just means "different of", some languages uses !=, others (like SQL) <>
not equals. See here for a list of conditions
I'm surprised nobody mentioned the null special case. I think the meaning of <> is more something like
has a value which is not equal to
In this case it filters out items which have ordid 605 and items which have a null ordid.
It may be obvious in this context that ordid is never null, but it is never hurts to remember that null is not <> from 605 (or from anything).
It means not equal to
Should I use != or <> for not equal in TSQL?
Have a look at the link. It has detailed explanation of what to use for what.
It (<>) is a function that is used to compare values in database table.
!= (Not equal to) functions the same as the <> (Not equal to) comparison operator.
It means not equal to, this is a good method to exclude certain elements from your query. For example lets say you have an orders tables and then you have OrderStatusID column within that table.
You also have a status table where
0 = OnHold,
1 = Processing,
2 = WaitingPayment,
3 = Shipped,
4 = Canceled.
You can run a query where
Select * From [Orders] where OrderStatusID <> 4
this should give you all the orders except those that have been canceled! :D

What does "WHERE id <> 0" clause mean in SQL?

Query: SELECT id, name, FROM users u WHERE **id <> 0** LIMIT 50 OFFSET 0
What does the clause id <> 0 mean here? Does it mean:
id is less than zero or id is greater than zero
<> means "not equal" (it can also be written as != with some DBMS)
It means not equal and apparently I have to submit at least 30 characters for my answer.
It means, "where ID is different from 0".
So, both greater than or less than 0.
it means that you are fetching all records with an id different than 0 (zero), I've sometimes used this just to check if some record is already saved (if the record has an ID it means is saved).
It means only include results who's field id has a value of greater or smaller than 0, basically records that have non-zero id's - but really this should not be possible, if it is then I'd recommend reconsidering your table designs.