I feel like this is a pretty basic SQL question but I am having trouble searching for the answer.
Essentially the logic I want to write in my SQL statement is this.
When doing an update on a row instead of just blanking out the data there add it together.
so if I have a row "9/19/13" | 0 | 1 | 0 and now I want to update that row with this entry "9/19/13" | 0 | 1 | 0 I get "9/19/13" | 0 | 2 | 0.
My current update command looks like so.
UPDATE entries(Date, John, Mark, Casey) SET (#Date, #John, #Mark, #Casey) WHERE(Date = #Date);
I could easily do it in my actual code where I would retrieve the entry increment it then just do a regular update, but I feel like it should be possible to to do it with straight SQL, and would be cleaner.
Is this what you mean?
-- #John, #Mark, #Casey are set in advance
UPDATE entries(Date, John, Mark, Casey)
SET (#Date, John + #John, Mark + #Mark, Casey + #Casey)
WHERE (Date = #Date);
calling update is just setting the values in the db to be the values you pass in, not the existing value added (in the case of numbers) to the value you're updating with.
it would be much simpler to just increment the value before update as you already have it.
Related
it is possible to store a function IN the table to automatically sum a group of columns and store the result in a final column?
ie:
+----+------------+-----------+-------------+------------+
| id | appleCount | pearCount | bananaCount | totalFruit |
+----+------------+-----------+-------------+------------+
| 1 | 300 | 60 | 120 | 480 |
+----+------------+-----------+-------------+------------+
where the column totalFruit is automatically calculated from the previous three columns and updated as the other columns update. in this specific application, there is ONLY going to be the one row. it would be spanky-handy to be able to just push the updated counts and then pull the calculated total out. i seem to recall reading about this ability somewhere, but for the life of me, i can't recall where... :poop:
if there is not way to do this, that's cool. but if there is... :smile:
TIA!
WR!
Yes, it is possible. But is it worth it? It is simple enough to do
SELECT ...
appleCount + pearCount + bananaCount AS totalFruit
...
See MariaDB Generated Columns for how to generate the extra column -- either as a real extra column or "virtual". What version of MariaDB?--There are a number of changes over time.
(MySQL users: 5.7.6 has a similar MySQL Generated Columns.)
I stumbled upon a very strange behaviour while working on some T-SQL Code.
I am working on a SQL Server 2008 R2 SP2 (build nr.: 10.50.4000).
My question to you guys is if anybody has seen such a behaviour before or if anybody might be able to explain it to me.
So,
What's the situation?
We have a table, which looks like that:
product_number | id_object | position_in_product
---------------------------------------------------
1 | 101 | 1
1 | 102 | 1
1 | 103 | 1
2 | 201 | 1
2 | 202 | 1
2 | 203 | 1
Multiple object ids are allocated to one product number. The order should be defined by the position_in_product column. The funny part lies exactly in establishing that order.
Of course, after doing that the table should look like this:
product_number | id_object | position_in_product
---------------------------------------------------
1 | 101 | 1
1 | 102 | 2
1 | 103 | 3
2 | 201 | 1
2 | 202 | 2
2 | 203 | 3
What's going on?
To update the order column we create a cursor with the following statement:
DECLARE
table_runner CURSOR LOCAL FORWARD_ONLY FOR
SELECT id_object, product_number
FROM table
WHERE ident = #ident
ORDER BY product_number
By using this cursor and counting the rows with the same product_number we should be able to update the position_in_product column. (This has worked in every installation until now)
To move the cursor to the next row we use this:
FETCH next from table_runner
INTO #table_runner$id_object, #table_runner$product_number
The whole function looks like this:
OPEN table_runner
FETCH next from table_runner
INTO #table_runner$id_object, #table_runner$product_number
while ##FETCH_STATUS = 0
BEGIN
/* update_logic */
FETCH next from table_runner
INTO #table_runner$id_object, #table_runner$product_number
END
CLOSE table_runner
And that is the part, that does not work as expected.
The fetch will not give me the next row. I am getting always the same result row.
The while loop does never end, the fetch_status is always 0, but the result stays the same.
The Workaround
After searching the web for quite a while without any results i decided to try a more pragmatical way and put another FETCH statement in.
I know that the id_object variable is unique and has to change in every loop cycle,
so i remembered the last fetched id and put this under the loop fetch statement:
if #id_object_memory = #table_runner$id_object
begin
FETCH next from table_runner
INTO #table_runner$id_object, #table_runner$product_number
set #id_object_memory = #table_runner$id_object
end
else
set #id_object_memory = #table_runner$id_object
With that the loop works as expected, the column in question is updated as it should and the cursor will reach the end of the result set.
The big ?
Has anyone any explanation for that?
There are more cursor defined in the same procedure and they all work as expected.
I have absolute no clue how to explain this.
So, thanks for reading ;)
I can't help with the cursor issue, I've never seen this before, but should point out you don't need a cursor at all to do this update. You can simply use:
WITH CTE AS
( SELECT Product_Number,
ID_Object,
Position_in_Product,
RowNumber = ROW_NUMBER() OVER(PARTITION BY Product_Number
ORDER BY id_object)
FROM T
WHERE ident = #ident
)
UPDATE CTE
SET Position_in_Product = RowNumber;
Example on SQL Fiddle
You possibly don't even need to store this column, and can just use ROW_NUMBER in a query where the position_in_product is required.
Cursors are so 2000 ;-)
Seriously though; avoid cursors at all costs. Set-based operations > looping.
Just create a view with the following:
CREATE VIEW your_view
AS
SELECT product_number
, id_object
, Row_Number() OVER (PARTITION BY product_number ORDER BY id_object) As position_in_product
FROM your_table
;
No need to ever perform the update; the row numbers will "automatically" recalculate.
My website attacked and hackers adds same string to all of my rows.
For example if the value of a row was "True value" they changed it to "True Value HACKED STRING ... HACKED by .. "
Unfortunately my site have lots of data and I can't change them one by one, but fortunately same data adds to all rows.
I want an SQL statement that removes all HACKED STRING from all rows.
You can do that quickly by removing the string with REPLACE function
Example TableA
id | Name
--------------
1 | Good HACKED BY XX
2 | We know HACKED BY XX
3 | Goodbye HACKED BY XX
Sql
UPDATE TableA
SET Name = REPLACE(Name, ' HACKED BY XX', '');
This will make you table look like this
id | Name
--------------
1 | Good
2 | We know
3 | Goodbye
Hy everyone,
Long time reader, first time poster.
This sounds like it should be really simple but I can't find the solution anywhere. I'm building a ratings system where people can rate if something is active or not. It has its own little logic but for it to work I need to.
check the items rating
depending on the current rating change it to a pre set amount.
I could hard code it in PHP with two SQL statements but I'm sure using a single stored procedure (one for vote up, another for vote down) will be much faster.
example table:
item_id | item_rating
---------------------
10 | 1
logic to vote item_rating up:
if | then
---------
0 | 1
1 | 2
-1 | 1
-2 | 1
2 | 2
logic to vote item_rating down:
if | then
---------
0 | -1
1 | -1
-1 | -2
-2 | -2
2 | -1
I know a simple points based system would be easier but due to the nature of the system this is the simplest solution I could find.
Can someone explain how I would use IF statements in SQL to achieve this? I'm sure the answer is really obvious to someone in the know.
(btw using the latest version of MySQL)
Is this what you're looking for? Here's an upvote:
UPDATE rating
SET item_rating = IF(item_rating < 1, 1, 2);
Here's a downvote:
UPDATE rating
SET item_rating = IF(item_rating > -1, -1, -2);
This is untested, but I think it should work.
update items i
set item_rating = (select i.item_rating + `then` from item_rating
where `if` = i.item_rating)
where i.item_id = 10
I am using pawn script for something, and everything works great except for one of my queries. For some reason, it will not work, and I am hoping it is simple enough someone can spot my mistake as I have been banging my head on it for days.
http://ampaste.net/m6a887d30
The two highlighted lines are the queries that are not working. The other one works fine, but the values for 'class1kills' and 'class2kills' remain at 0. Here is a screenshot from phpmyadmin incase I did something silly.
http://brutalservers.net/sql.png
Your SQL-code, copied from where you pasted it:
UPDATE global SET class1kills = class1kills + 1
In addition to what the user Marcus said, even if there is a row in the table, but it's value is NULL, then adding to the value will not work. You will have to set it to an integer value first, such as 0.
E.g.:
mysql> create table mytable(a int);
mysql> insert into mytable(a) values (0),(NULL);
mysql> select * from mytable;
+------+
| a |
+------+
| 0 |
| NULL |
+------+
mysql> update mytable set a = a+1;
mysql> select * from mytable;
+------+
| a |
+------+
| 1 |
| NULL |
+------+
The NULL value was not updated!
By the way, are you sure you want to update the complete table?
Try inserting a row into global, and then updating it.
Note that without a WHERE clause on your UPDATE statement, all rows will be updated.
Is MySQL case sensitive when it comes to comparing strings? Otherwise check encodings etc. That is all I can think of.
Sorry guys, turns out it is a bug with the scripting language. For some reason two queries right after each other causes the second one not to be called properly.
Thank you all for all of the help!