I'm just getting into SQL and need a hand with some of the basics.
I'm trying to write a query that will allow me to find values between range in one column of a table and replace all values in that range with a single value that I would specify with an UPDATE or REPLACE function.
I've gotten as far as
SELECT *
FROM (Table_A)
WHERE Column BETWEEN #a and #b
ORDER by Column desc
but I get back 0 results even though I know there are tons of values between #a and #b.
Select with BETWEEN
SELECT * FROM Table_A WHERE column BETWEEN 10 AND 30
Update
update Table_A set column = 'NEW_VALUE' where column BETWEEN 10 AND 30
Replace
// string hallo2 -> will be change to hallo3
update Table_A set column = replace(column, "2", "3") where column BETWEEN 10 AND 30
Related
I have a table named as mytable where it has column named a_column.currently it is null valued and it has 100 rows. I just need to know how to set the value of first 50 rows as ABC and rest 50 rows as XYZ. I have tried to use below queries but i was unsuccessful. kindly suggest me the query.
UPDATE mytable
SET a_column= 'ABC';
INSERT INTO table (mytable) VALUES ("ABC/XYZ")
chamath
You can use following query to do that.
UPDATE mytable
SET a_column= (CASE WHEN id > 50 THEN 'XYZ' ELSE 'ABC' END);
I'm trying to update a certain column of certain row WHERE id is certain value. The thing is, the number/names of columns are variable, and so are their respective ids.
For example:
UPDATE table SET column1="hello" WHERE id = 5
UPDATE table SET column2="cucumber" WHERE id = 6
How can I do a single mysql query in PDO to do this?
First thing I tried is...
UPDATE table SET column1="hello", column4="bye" WHERE id IN(5, 6)
But that query will update BOTH of those columns in rows where it finds BOTH of those ids, and that's not what I'm looking for. Is it only possible to do this query by query?
Keep in mind that the argument after SET is variable, so the columns to be updated, their values and their respective ids are also variable.
A solution where you can just purely bind values would be great, but if I have to build the query string with escaped variables, then that's OK too.
Thank you.
You can do this
UPDATE table t1 JOIN table t2
ON t1.id= 5 AND t2.id= 6
SET t1.column1= 'hello',
t2.column2 = 'cucumber';
Or if you want to do this on a single column
UPDATE table
SET column2 = CASE id
WHEN 5 THEN 'hello'
WHEN 6 THEN ''
END
WHERE id IN(5, 6);
I have an insert that uses a GROUP_CONCAT. In certain scenarios, the insert fails with Row XX was cut by GROUP_CONCAT. I understand why it fails but I'm looking for a way to have it not error out since the insert column is already smaller than the group_concat_max_len. I don't want to increase group_concat_max_len.
drop table if exists a;
create table a (x varchar(10), c int);
drop table if exists b;
create table b (x varchar(10));
insert into b values ('abcdefgh');
insert into b values ('ijklmnop');
-- contrived example to show that insert column size varchar(10) < 15
set session group_concat_max_len = 15;
insert into a select group_concat(x separator ', '), count(*) from b;
This insert produces the error Row 2 was cut by GROUP_CONCAT().
I'll try to provide a few clarifications -
The data in table b is unknown. There is no way to say set group_concat_max_len to a value greater than 18.
I do know the insert column size.
Why group_concat 4 GB of data when you want the first x characters?
When the concatenated string is longer than 10 chars, it should insert the first 10 characters.
Thanks.
Your example GROUP_CONCAT is probably cooking up this value:
abcdefgh, ijklmnop
That is 18 characters long, including the separator.
Can you try something like this?
set session group_concat_max_len = 4096;
insert into a
select left(group_concat(x separator ', '),10),
count(*)
from b;
This will trim the GROUP_CONCAT result for you.
You temporarily can set the group_concat_max_len if you need to, then set it back.
I don't know MySQL very well, nor if there is a good reason to do this in the first place, but you could create a running total length, and limit the GROUP_CONCAT() to where that length is under a certain max, you'll still need to set your group_concat_max_len high enough to handle the longest single value (or utilize CASE logic to substring them to be under the max length you desire.
Something like this:
SELECT SUBSTRING(GROUP_CONCAT(col1 separator ', '),1,10)
FROM (SELECT *
FROM (SELECT col1
,#lentot := COALESCE(#lentot,0) + CHAR_LENGTH(col1) AS lentot
FROM Table1
)sub
WHERE lentot < 25
)sub2
Demo: SQL Fiddle
I don't know if it's SQL Fiddle being quirky or if there's a problem with the logic, but sometimes when running I get no output. Not big on MySQL so could definitely be me missing something. It doesn't seem like it should require 2 subqueries but filtering didn't work as expected unless it was nested like that.
Actually, a better way is to use DISTINCT.
I had a situation to add new two fields into existing stored procedure, in a way that a value for that new fields had been obtained by a LEFT JOIN, and because it may have contained a NULL value, a single "concat" value was multiplicated for some cases more than a 100 times.
Because, a group with that new field value contained many NULL values, GROUP_CONCAT exceeded maximum value (in my case 16384).
How can I store only 10 rows in a MySQL table? The older rows should be deleted when a new row is added but only once the table has 10 rows.
Please help me
You could achieve this with an after insert trigger, delete the row where it is min date. e.g. DELETE FROM myTable WHERE myTimestamp = (SELECT MIN(myTimestamp) FROM myTable) but that could in theory delete multiple rows, depending on the granularity of your updates.
You could have an incrementing sequence, and always just delete the min of that sequence.
The question is why you'd want to do this though? It's a slightly unusual requirement.
A basic example (not validated/executed, I don't have mySQL on this particular machine) would look something like.
CREATE TRIGGER CycleOldPasswords AFTER INSERT ON UserPasswords FOR EACH ROW
set #mycount = SELECT COUNT(*) FROM UserPasswords up where up.UserId = NEW.UserId;
if myCount >= 10 THEN
DELETE FROM UserPasswords up where up.Timestamp = (SELECT min(upa Timestamp) FROM UserPasswords upa WHERE NEW.UserId = upa.UserId) AND NEW.UserId = up.UserId;
END
END;
You can retrieve the last inserted id when your first row is inserted, and store it in a variable. When 10 rows are inserted, delete the row having id < id of the first inserted record. Please try it.
first of all insert all values using your insert query
and then run this query
delete from table_name where (cond) order by id desc limit 10
must specify an id or time in one column
Two questions:
1)
There are several tables that are used as an archive for other tables.
To do so, there is a
INSERT INTO data_archive_table (SELECT * FROM data_table)
The problem is that the data_table.id should be kept as data_archive_table.old_id.
Is there a way to write a query that will look like: SELECT *, id AS old_id FROM data_table, while the results columns will have ONLY the old_data column, and NOT the original id column?
Using all column names is the only option I see, but I prefer to avoid it.
2)
I want to add a virtual column named deleted_time to the insertion query, that will hold the current time.
Can it be done? if so - how ?(tutorials will be great)
Try this:
1.) You can use something like this query:
INSERT INTO data_archive_table
SELECT id AS old_id -- be sure that data_archive_table has column oldID
,... -- You need to specify the names of the columns
FROM data_table
WHERE id = 'IDHERE' -- If you want to have condition.
2.) For this, you can add the value directly in you select statement
INSERT INTO `tableName`
SELECT colA,
colB,
, ...
, NOW() as deleted_time -- NOW() is a function in MySQL
FROM `sourceTable`
WHERE colA = 'IDHERE' -- If you want to have condition.
NOW() in MySQL