Update lot of data, date ( +1hour ), contraints uniq - mysql

I try to add 1hours for each value after specific date...
I have table like this :
Colonne Type
id int(11)
date datetime
value double
kind varchar(190)
data_id int(11) NULL
I have uniq constraints on 'date' . 'kind' . 'data_id'
I try :
update data set `date` = ADDTIME(`date`, '01:00:00') WHERE `date` > '2019-03-31 02:00:00';
But i get Error
Duplicate entry '2019-03-31 04:05:00-ManualDataValue-1' for key 'UNIQ_DATE_KIND_DATA_ID
I understand the error, the value exists, but I need to "move" all data ...
So if the request is performed in one block and the unique constraints is checked at the end, technically there is no error ...
How to perform this ?
( PS: SELECT * FROM data WHERE date > '2019-03-31 02:00:00' return 1,198,778 entry, so i can't do this manualy :/ )

Try:
update data set `date` = ADDTIME(`date`, '01:00:00') WHERE `date` > '2019-03-31 02:00:00' ORDER By date DESC
See this SO for more explanations.

Related

Mysql unable to select datetime column

I'm trying to SELECT rows that matches datetime in my column. I have a table containing mDTS set as DATETIME (with no curly braces).
My table looks something like this:
mID
mDTS
mDTE
1
10/08/2021 10:41:47
11/08/2021 10:41:47
2
12/08/2021 10:42:34
13/08/2021 10:42:34
CREATE TABLE tb_cyc (
mID int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID cycle',
mDTS datetime DEFAULT CURRENT_TIMESTAMP COMMENT 'Data inizio ciclo',
mDTE datetime DEFAULT '0000-00-00 00:00:00' COMMENT 'Data fine ciclo',
PRIMARY KEY (mID)
)
I'm trying to run the following query but it returns an empty set.
SELECT * FROM tb_cyc WHERE mDTS = '12/08/2021 10:42:34'
I've also tried:
SELECT * FROM tb_cyc WHERE mDTS LIKE '12/08/2021 10:42:34'
and
SELECT * FROM tb_cyc WHERE mDTS = '12/08/2021 %'
But none of this seems to work.
What am I doing wrong?
Change the format of the date in WHERE clause:
WHERE mDTS = '2021-08-12 10:42:34'
What happens is that mDTS is a datetime; when compared with a string MySQL will treat the string as a date/time. The literal value 12/08/2021 10:42:34 will generate the following warning:
Incorrect datetime value: '12/08/2021 10:42:34' for column 'mDTS' at row 1

If using sum>100, sums under 100 will still show

I have a table with some data. Many of these data have the name ICA Supermarket with different sums for every data. If I use the following SQL query, it will also show data with the sum under 100. This applies also if I change >= '100' to a higher digit, for an example 200.
SELECT *
FROM transactions
WHERE data_name LIKE '%ica%'
AND REPLACE(data_sum, '-', '') >= '100'
If I change >= to <= no data will show at all. Here's how the table looks like:
CREATE TABLE IF NOT EXISTS `transactions` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`data_name` tinytext NOT NULL,
`data_sum` decimal(10,2) NOT NULL
UNIQUE KEY `id` (`id`)
)
Is it because data_sum is a DECIMAL? How can I prevent this from happening? I want to use DECIMAL for sums :)
Note: data_sum will also contain sums that are above minus.
REPLACE(data_sum, '-', '') returns a string. Also '100' is a string. So a string compare will be used. You should use ABS function:
SELECT *
FROM transactions
WHERE data_name LIKE '%ica%'
AND ABS(data_sum) >= 100
Are you looking for values >= 100 and <= -100? Or just values <= -100.
If the latter, then
... AND data_sum <= -100
This applies to DECIMAL, INT, FLOAT, etc.
Every table 'needs' a PRIMARY KEY. Promote that UNIQUE to PRIMARY.

MySQL - get date column from a table

I have a MySQL db with a MappingTable which consists of two columns. First column is a date column and another is ID - Autoincrement int column. I created this table for mapping dates and the ID's. When I query the date column with dates to retrieve the ID, no rows are getting selected. Any reason?
I tried
date_format in the SELECT query
str_to_date while checking in the WHERE clause
Compared like current_date > "2016-07-12" AND current_date <= "2016-07-12"
IfI compare LIKE "2016-07-1%" I'm getting matching rows but if I select "2016-07-12%" though there are matching rows, it is giving 0 rows.
I defined my column as DATE only.
Anything I'm missing here?
CREATE TABLE `mapping_table` (
`Current_date` date DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8;
My question is, I want to select something like this.
select id from mapping_table where current_date="2016-07-12";
I tried with all approaches as mentioned above, but no rows are not retrieving.
use back tick on columns and table names so it wont be read/parse as keyword.
select `id` from `mapping_table` where `current_date` = "2016-07-12";
In the sample you provided you should use a date_format
select id from mapping_table where current_date= DATE_FORMAT("2016-07-12",'%Y-%d-%m') ;
or use a range
select id from mapping_table where current_date
BETWEEN DATE_FORMAT("2016-07-12",'%Y-%d-%m')
and DATE_FORMAT("2016-07-10",'%Y-%d-%m')

SQL: UPDATE query which doesn't affect timestamp on the row

I have some SQL code below which enables me to change all instances of quantities that are '0' and change them to '1' within the 'quantity' column only. It works ok but...
What I am trying to do, however, is not affect the timestamp column (called 'entry_date') on the affected rows ie. keep the original time the entry was made. When I run this query it replaces the time the entry was originally made with the time the query below was ran.
How do I get around this? I have basic-intermediate PHP knowledge but my SQL knowledge isn't great. Any help would be appreciated.
UPDATE databasename.tablename SET quantity = '1'
WHERE tablename.quantity = '0';
You could try something like this:
UPDATE databasename.tablename SET quantity = '1', entry_date = entry_date
WHERE tablename.quantity = '0';
and see if it doesn't override the behaviour specified by the ON UPDATE CURRENT_TIMESTAMP.
First, DESCRIBE tablename, and note "entry_date" has Extra info "on update CURRENT_TIMESTAMP". That's the behavior you want to avoid.
Next, ALTER TABLE tablename MODIFY COLUMN entry_date TIMESTAMP [NULL | NOT NULL] DEFAULT CURRENT_TIMESTAMP;
(You specify 'NULL' or 'NOT NULL' as appropriate.)
Finally, DESCRIBE tablename again, and note that the Extra info is gone.
When you want timestamp field entry_date to not change automatically on update.. you need following query to execute before any update query on your table
ALTER TABLE `tableName` CHANGE `entry_date` `entry_date` TIMESTAMP NOT NULL
DEFAULT CURRENT_TIMESTAMP
Opposite : After this if you again want timestamp field entry_date to change automatically on update.. you need following query to execute before any update query on your table
ALTER TABLE `tableName` CHANGE `entry_date` `entry_date` TIMESTAMP ON UPDATE
CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP

Update a field based off of the current value (in mysql)

I have a table similar to
CREATE TABLE `mytable` (
`ID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`Time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
KEY `time` (`Time`),
) ENGINE=MyISAM AUTO_INCREMENT=2373485 DEFAULT CHARSET=latin1
I had a weird issue with daylight savings time, and now I need to update rows with IDs 2370144 through 2373391 so that the Time values are six hours less than their current values.
I can select the affected rows with
SELECT * FROM mytable WHERE ID >= 2370144 AND ID <= 2373391
How do I update these entries so that the new timestamp is six hours less than the old value?
I think this will work
UPDATE mytable SET Time = date_sub(Time, INTERVAL 6 HOUR) WHERE id BETWEEN 2370144 AND 2373391;
UPDATE mytable
SET `Time` = (`Time` - INTERVAL 6 HOUR)
WHERE ID >= 2370144
AND ID <= 2373391
Expanding on this a little bit, when feasible I would typically run a SQL query to generate a .sql file that contains one update statement per row, then execute that sql file to update the rows. Since you are only updating about 3,000 rows this should be feasible for you.
This dump and load approach has a couple of benefits:
You can save the SQL script as an
audit record of what you changed.
You can include both the ID and the Time
value in the SQL script. That way if
you accidentally run the script more
than once you don't end up changing
the value to something incorrect. For
example, if you ran my original
update twice the values would end up
6 hours too low, but if you use the
dump-and-load approach and run the
script twice, the second time it
won't change the records because the
where clause will no longer match.
Here's an example of the dump-and-load approach:
select concat('update mytable set `Time` = ''',
`Time` - interval 6 hour,
''' where id = ',
id,
' and `Time` = ''',
`Time`,
''';') as sql_stmt
into outfile '/tmp/mytable.update.dstfix.20110315.sql'
from mytable
WHERE ID >= 2370144
AND ID <= 2373391;
\. /tmp/mytable.update.dstfix.20110315.sql