Why will this not update 501 records? What's wrong with my query?
MariaDB [contacts]> UPDATE history h, phone_corrections t SET h.contact = t.new_nmbr WHERE h.contact = t.old_nmbr;
Query OK, 0 rows affected (0.03 sec)
Rows matched: 501 Changed: 0 Warnings: 0
MariaDB [contacts]>
FIXED! There were several records where the wrong_nmbr field was the same value as the right_nmbr field. Sorry for the post.
Related
This question already has answers here:
MySQL select 10 random rows from 600K rows fast
(28 answers)
quick selection of a random row from a large table in mysql
(24 answers)
Closed last year.
I have a very large table with about 6.6 million records and I want to select a random sample of 100,000 records
SELECT column FROM table
ORDER BY RAND()
LIMIT 100000
Is EXTREMELY SLOW on each record.
I have not found a solution that works with MySQL/MariaDB to extract a random sample of 100,000 records.
Please advise.
Thank you.
You may try to decrease the amount of rows to be sorted.
Example:
Create source data
mysql> create table test (id int auto_increment primary key, val int);
Query OK, 0 rows affected (0.05 sec)
mysql> set ##cte_max_recursion_depth := 10000000;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test (val) with recursive cte as ( select 1 num union all select num+1 from cte where num < 6600000 )select rand() * 1000000000 from cte;
Query OK, 6600000 rows affected (1 min 48.62 sec)
Records: 6600000 Duplicates: 0 Warnings: 0
mysql> create table tmp (val int);
Query OK, 0 rows affected (0.05 sec)
Insert without sorting
mysql> insert into tmp select val from test limit 100000;
Query OK, 100000 rows affected (1.93 sec)
Records: 100000 Duplicates: 0 Warnings: 0
Insert with random sorting
mysql> insert into tmp select val from test order by rand() limit 100000;
Query OK, 100000 rows affected (26.31 sec)
Records: 100000 Duplicates: 0 Warnings: 0
Insert with random selection (1.1 is overage coefficient)
mysql> insert into tmp select val from test where rand() < 1.1 * 100000 / 6600000 limit 100000;
Query OK, 100000 rows affected (15.89 sec)
Records: 100000 Duplicates: 0 Warnings: 0
Insert with random selection (1.1 is overage coefficient) and random sorting
mysql> insert into tmp select val from test where rand() < 1.1 * 100000 / 6600000 order by rand() limit 100000;
Query OK, 100000 rows affected (19.26 sec)
Records: 100000 Duplicates: 0 Warnings: 0
Overage coefficient may be adjusted. If you decrease it then you'll improve the query (slightly) but the probability that the amount of output rows will be less than needed 100k rows will increase.
I have the code below but for some reason in mysql it gives error when running the second alter table statement to add a new column. The error i get is Invalid default value for 'start'
If i comment out the second alter table it works because the data gets inserted.
CREATE TABLE users (
id int unsigned NOT NULL PRIMARY KEY,
name varchar(255) NOT NULL
);
ALTER TABLE users ADD start datetime DEFAULT (DATE_SUB(now(), INTERVAL -1 DAY)) NOT NULL;
insert into users (id, name) values (1, 'usera'), (2, 'usera');
ALTER TABLE users ADD anotherDate datetime DEFAULT (now()) NOT NULL; -- This errors
select * from users;
Full error is: ERROR 1067 42000 Invalid default value for 'start'
Fiddle to show error: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=2df3b421793a7470a321247abec85b47
I started with sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION':
mysql> ALTER TABLE users ADD start datetime DEFAULT (DATE_SUB(now(), INTERVAL -1 DAY)) NOT NULL;
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql>
mysql> insert into users (id, name) values (1, 'usera'), (2, 'usera');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> set sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_ZERO_IN_DATE';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> ALTER TABLE users ADD anotherDate datetime DEFAULT (now()) NOT NULL;
Query OK, 2 rows affected (0.07 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> set sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_ZERO_IN_DATE,NO_ZERO_DATE';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> ALTER TABLE users ADD anotherDate2 datetime DEFAULT (now()) NOT NULL;
ERROR 1067 (42000): Invalid default value for 'start'
mysql>
Both NO_ZERO_IN_DATE and NO_ZERO_DATE are deprecated according to https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#sqlmode_no_zero_in_date
this is on MySQL 8.0.22
EDIT:
oops, i must read it myself 😉
mysql> set sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show warnings;
+---------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Level | Code | Message
|
+---------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Warning | 3135 | 'NO_ZERO_DATE', 'NO_ZERO_IN_DATE' and 'ERROR_FOR_DIVISION_BY_ZERO' sql modes should be used with strict mode. They will be merged with strict mode in a future release. |
+---------+------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
I have a column in the database's table with data format like this "000011" and an SQL query like:
SELECT *
FROM table
WHERE a = 000010 OR a = 000001 or a = 000011
But if the value is 111111. It will have a lot of OR condition in it.
If data format like 001 (3 digits) it's can use wildcard ( _ )to do this, but I'm stuck when trying to use it in case (6 digits).
Please help me to find other ways?
First, you can use in:
SELECT *
FROM table
WHERE a in (000010, 000001, 000011)
But, I suspect your "data" is actually an integer and you want boolean & or |:
WHERE (a & 000011)
If you want to show data that contains a 1 then use LIKE
SELECT *
FROM table
WHERE a LIKE '%1%'
SELECT *
FROM table
WHERE position('1' in a) > 0
From what I understand you want to find all rows where the binary representation is less than your input. If that is the case, you could use the BINARY function to get the result you want:
mysql> create table bintab (a varchar(10));
Query OK, 0 rows affected (0.07 sec)
mysql> insert into bintab values('000001');
Query OK, 1 row affected (0.04 sec)
mysql> insert into bintab values('000010');
Query OK, 1 row affected (0.01 sec)
mysql> insert into bintab values('000011');
Query OK, 1 row affected (0.01 sec)
mysql> insert into bintab values('000100');
Query OK, 1 row affected (0.00 sec)
mysql> insert into bintab values('000101');
Query OK, 1 row affected (0.00 sec)
mysql> insert into bintab values('000110');
Query OK, 1 row affected (0.01 sec)
mysql> insert into bintab values('000111');
Query OK, 1 row affected (0.00 sec)
mysql> select * from bintab where binary(a) < binary('000100');
+--------+
| a |
+--------+
| 000001 |
| 000010 |
| 000011 |
+--------+
3 rows in set (0.00 sec)
I issued an update command which gave the following output:
Query OK, 1 row affected, 2 warnings (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 2
So I was looking for the log file which might have the details of warnings that were reported as a result of the above command.
Note: I had exited from the session so Show Warnings returns Empty Set.
I'm getting warnings when updating a table but the warnings are not showing. Through tedious and lengthy trial-and-error, the cause of the warnings has been tracked down to the INNER JOIN. I need a better way to debug a warning.
Setup is OK. I know warnings are on because MySQL command prompt was started with option '--show-warnings' and warnings are turned on warnings with '\W':
mysql> \W
Show warnings enabled.
mysql> show variables like '%warn%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_warnings | 0 |
| sql_warnings | ON |
| warning_count | 0 |
+---------------+-------+
3 rows in set (0.01 sec)
To make sure warnings were on, I forced a truncating warning on a VARCHAR(255) field:
mysql> UPDATE course
-> SET course.transcript_title = 'Field transcript_title is VARCHAR(255). This is over 255 characters to force truncating warning. Field transcript_title is VARCHAR(255). This is over 255 characters to force truncating warning. Field transcript_title is VARCHAR(255). This is over 255 characters to force truncating warning.'
-> WHERE course.title LIKE '%SLP%'
-> AND course.year = 2008
-> AND course.gid = 35;
Query OK, 104 rows affected, 104 warnings (0.19 sec)
Rows matched: 104 Changed: 104 Warnings: 104
Warning (Code 1265): Data truncated for column 'transcript_title' at row 1
Warning (Code 1265): Data truncated for column 'transcript_title' at row 2
.... etc.
I want to get the warning from this type of query:
mysql> UPDATE course
-> INNER JOIN group_info ON course.gid = group_info.id
-> SET course.description = 'Foo.'
-> WHERE course.title LIKE '%SLP%'
-> AND course.year = 2008 AND group_info.id = 35;
Query OK, 0 rows affected (0.02 sec)
Rows matched: 104 Changed: 0 Warnings: 104
mysql> SHOW WARNINGS;
Empty set (0.00 sec)
From trial and error, I know the error is from having the INNER JOIN clause. If I remove the INNER JOIN and directly use the gid (group id) field in the course table, then no warnings:
mysql> UPDATE course
-> SET course.description = 'Bar.'
-> WHERE course.title LIKE '%SLP%'
-> AND course.year = 2008
-> AND course.gid = 35;
Query OK, 104 rows affected (0.01 sec)
Rows matched: 104 Changed: 104 Warnings: 0
But I need the INNER JOIN clause because what I really want to do is use the more friendly 'name' field in the joined 'group_info' table:
UPDATE course
INNER JOIN group_info ON course.gid = group_info.id
SET course.description = 'Foo.'
WHERE course.title LIKE '%SLP%'
AND course.year = 2008
AND group_info.name = 'One-to-One Meeting Time';
I've been googling, reading, and debugging the warning for over 1 hour. I've searched for answers or explanations for why this would not show warnings but no luck.
How do I get warnings to show for the INNER JOIN type of UPDATE?