MySQL - Get all string sizes stored in a field - mysql

I would like to get all string sizes that are stored in a field myfield which is a varchar(128), along with their occurrences (i.e. the number of rows with that specific length). This is what I have so far:
MySQL > SELECT SUM(CHAR_LENGTH(myfield)=5) as occurr from mytable;
+--------+
| occurr |
+--------+
| 9194 |
+--------+
1 row in set (0.39 sec)
MySQL > SELECT SUM(CHAR_LENGTH(myfield)=6) as occurr from mytable;
+--------+
| occurr |
+--------+
| 11636 |
+--------+
1 row in set (0.44 sec)
MySQL > SELECT SUM(CHAR_LENGTH(myfield)=7) as occurr from mytable;
+--------+
| occurr |
+--------+
| 19022 |
+--------+
1 row in set (0.48 sec)
Is there a way to get this data with a single SQL command? Something like this output:
+--------+--------+
| length | occurr |
+--------+--------+
| 5 | 9194 |
+--------+--------+
| 6 | 11636 |
+--------+--------+
| 7 | 19022 |
+--------+--------+

You can simply use:
SELECT CHAR_LENGTH(myfield) AS length, COUNT(*) AS occurr
FROM mytable
WHERE CHAR_LENGTH(myfield) IN (5,6,7)
GROUP BY CHAR_LENGTH(myfield)
You can, of course, remove the WHERE clause, if you are not interested in some specific character lengths.

SELECT CHAR_LENGTH(my_field) ASlength, COUNT(*) ASoccurrFROMmytableGROUP BY CHAR_LENGTH(my_field)
I was still typing as the other answer came up. Basically the same - except no limit on what CHAR_LENGTH() is included.

SELECT CHAR_LENGTH(myfield) as length, COUNT(*) as occurence FROM mytable WHERE CHAR_LENGTH(myfield) BETWEEN 4 and 6 GROUP BY length
edit: I posted this more or less simultaniously to the identical answers above. I did of course not intend to steal an answer.

Related

Pattern for LIKE in SQL Statement

I would like to select all rows that start with any character.
SELECT * FROM table WHERE field LIKE '[a-z]%' ;
The type of rows I would like to find look like this:
ID DATA
993 DEF055900960
994 DEF055900961
995 DEF055900964
996 DEF056102254
997 DEF056131201
I have unsucessfully tried RLIKE and REGEXP and also added upper case A-Z ot the pattern.
Why is the following not working?
SELECT * FROM table WHERE field RLIKE '[a-z]' ;
SQL Fiddle Demo
I went through here to read about Pattern Matching in Mysql
Try this instead:
SELECT * FROM table WHERE field LIKE '[^A-Z]%';
Try this.
SELECT `firstname`
FROM `users`
WHERE firstname
REGEXP BINARY '^[A-Z]'
Use REGEXP
http://dev.mysql.com/doc/refman/5.1/en/regexp.html#operator_regexp
For example, assume we have this data set.
mysql> select * from a;
+------+
| b |
+------+
| abc |
| zxxb |
| kkfy |
| 0002 |
+------+
4 rows in set
We want to select everything with the a-z pattern
mysql> SELECT * FROM a WHERE b REGEXP BINARY '[a-z]';
+------+
| b |
+------+
| abc |
| zxxb |
| kkfy |
+------+
3 rows in set
SQLFiddle
For your data set
SQLFiddle
Use the regular expression [a-zA-Z0-9]
mysql> SELECT * FROM a WHERE b REGEXP BINARY '[a-zA-Z0-9]';
+--------------+
| b |
+--------------+
| DEF055900960 |
| DEF055900961 |
| DEF055900964 |
| DEF056102254 |
| DEF056131201 |
+--------------+
5 rows in set

Find and replace a specific part of a string with a backslash in a field

For example this is myTable:
| i | data |
+---+---------+
| 1 | d\one |
| 2 | d\two |
| 3 | d\three |
But I want to change it to:
| i | data |
+---+-------+
| 1 | one |
| 2 | two |
| 3 | three |
I know how to find a specific part of a string with a backslash in a field:
SELECT * FROM myTable WHERE data LIKE 'd%\%'
I know how to find & replace a field a value, only this query won't work:
UPDATE myTable SET data=REPLACE(data,'d\','') WHERE data LIKE 'd%\%'
You need to escape the backslash
UPDATE myTable
SET data = REPLACE(data,'d\\','')
WHERE data INSTR('d\\') = 1
SQLFiddle demo
I hope you should put triple slash \\\ instead of double slash \\ in Like Clause. As I have tried I am unable to pick data from using \\
SELECT * FROM mytable WHERE data LIKE 'd\\%';
Empty set (0.00 sec)
mysql> SELECT * FROM mytable WHERE data LIKE 'd\\\%';
+---------+
| data |
+---------+
| d\one |
| d\two |
| d\three |
+---------+
3 rows in set (0.00 sec)
mysql> SELECT REPLACE(data,'d\\','') FROM mytable WHERE data LIKE 'd\\\%';
+------------------------+
| REPLACE(data,'d\\','') |
+------------------------+
| one |
| two |
| three |
+------------------------+
3 rows in set (0.00 sec)
mysql> UPDATE mytable SET data = REPLACE(data,'d\\','') WHERE data LIKE 'd\\\%';
Query OK, 3 rows affected (0.06 sec)
Rows matched: 3 Changed: 3 Warnings: 0
mysql> SELECT * FROM mytable;
+-------+
| data |
+-------+
| one |
| two |
| three |
+-------+
3 rows in set (0.00 sec)
try this one..
UPDATE myTable SET `data`=REPLACE(`data`,'d\','');

Slow InfiniDB queries, what am I doing wrong?

I'm testing the InfiniDB community edition to see if it suits our needing.
I imported in a single table about 10 millions rows (loading of data was surprisingly fast), and I'm trying to do some query on it, but these are the results (with NON cached queries.. if query caching exists in InfiniDB):
Query 1 (very fast):
select * from mytable limit 150000,1000
1000 rows in set (0.04 sec)
Query 2 (immediate):
select count(*) from mytable;
+----------+
| count(*) |
+----------+
| 9429378 |
+----------+
1 row in set (0.00 sec)
Ok it seems to be amazingly fast.. but:
Query 3:
select count(title) from mytable;
.. still going after several minutes
Query 4:
select id from mytable where id like '%ABCD%';
+------------+
| id |
+------------+
| ABCD |
+------------+
1 row in set (11 min 17.30 sec)
I must be doing something wrong, it's not possible that it's performing this way with so simple queries. Any Idea?
That shouldn't be the case, there does appear to be something odd going on, see quick test below.
What is your server configuration: memory/OS/CPU and platform (dedicated, virtual, cloud).
Could I get the schema declaration and method to load the data?
Which version are you using? Version 4 community has significantly more features than prior versions, i.e. core syntax matches enterprise.
Cheers,
Jim T
mysql> insert into mytable select a, a from (select hex(rand() * 100000) a from lineitem limit 10000000) b;
Query OK, 10000000 rows affected (1 min 54.12 sec)
Records: 10000000 Duplicates: 0 Warnings: 0
mysql> desc mytable;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | varchar(32) | YES | | NULL | |
| title | varchar(32) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
mysql> select * from mytable limit 150000,1000;
+-------+-------+
| id | title |
+-------+-------+
| E81 | E81 |
| 746A | 746A |
. . .
| DFC8 | DFC8 |
| 2C56 | 2C56 |
+-------+-------+
1000 rows in set (0.07 sec)
mysql> select count(*) from mytable;
+----------+
| count(*) |
+----------+
| 10000000 |
+----------+
1 row in set (0.06 sec)
mysql> select count(title) from mytable;
+--------------+
| count(title) |
+--------------+
| 10000000 |
+--------------+
1 row in set (0.09 sec)
mysql> select id from mytable where id like '%ABCD%' limit 1;
+------+
| id |
+------+
| ABCD |
+------+
1 row in set (0.03 sec)

How to delete duplicate records but except one for Int?

Under my Table records for MySQL, i have these:
SELECT * FROM dbo.online;
+-------+
| Id |
+-------+
| 10128 |
| 10240 |
| 6576 |
| 32 |
| 10240 |
| 10128 |
| 10128 |
| 12352 |
+-------+
8 rows in set (0.00 sec)
How to make it to:
SELECT * FROM dbo.online;
+-------+
| Id |
+-------+
| 10128 |
| 10240 |
| 6576 |
| 32 |
| 12352 |
+-------+
8 rows in set (0.00 sec)
In other words, I want to do is, using DELETE command instead of SELECT * FROM dbo.online GROUP BY id.. So, any idea how?
Copy data to back up table with distinct, that steop eliminates duplicates
create table backUp_online as
SELECT distinct *
FROM online;
Clear source table
truncate table online
Copy data from back up to source table without duplicates
insert into online
select *
from backUp_online
There is a trick in MySQL:
ALTER IGNORE TABLE `dbo`.`online` ADD UNIQUE KEY `ukId`(`Id`)
This can also be useful.
Simplest query to do the same.
DELETE n1 FROM online n1, online n2 WHERE n1.id < n2.id AND n1.name = n2.name

How to filter the item in mysql database into given letter ranges

I have a query to filter the result in mysql database into given letter ranges: I want to display the items who starts with letter a-f. I uses this query but I think there is a better query to do that.
SELECT DISTINCT title FROM tables WHERE LEFT(title, 1) ='a' AND LEFT(title, 1)='b' ..... AND LEFT(title, 1)='f';
MySQL (and probably all databii) evaluate words that begin with 'B' as being greater than 'a' and less than 'c'.
So you can simply check for values between 'a' and 'f'.
SELECT DISTINCT title FROM tables WHERE title >= 'a' AND title < 'g';
This should be more efficient than a regex (much as I love Regular Expressions), and is easier to read.
You can use regex something like
SELECT DISTINCT title FROM tables WHERE title REGEXP '^[a-f]'
It's case insensitive. But you might want to remove DISTINCT if you do not want single result for uppercase and lowercase word. For example,
mysql> select * from name;
+------+--------+
| id | title |
+------+--------+
| 1 | anisgt |
| 1 | bnisgt |
| 1 | dnisgt |
| 1 | gnisgt |
| 1 | hnisgt |
| 1 | Hnisgt |
| 1 | Pnisgt |
+------+--------+
7 rows in set (0.00 sec)
mysql> SELECT DISTINCT title FROM name WHERE title REGEXP '^[f-z]';
+--------+
| title |
+--------+
| gnisgt |
| hnisgt |
| Pnisgt |
+--------+
3 rows in set (0.00 sec)
mysql> SELECT title FROM name WHERE title REGEXP '^[f-z]';
+--------+
| title |
+--------+
| gnisgt |
| hnisgt |
| Hnisgt |
| Pnisgt |
+--------+
4 rows in set (0.00 sec)
Edit#1 updated case for upper-case, lower case query and example for without distinct
However you can force case sensitivity using binary key word like
mysql> SELECT DISTINCT binary title FROM name WHERE title REGEXP '^[f-z]';
+--------------+
| binary title |
+--------------+
| gnisgt |
| hnisgt |
| Hnisgt |
| Pnisgt |
+--------------+
4 rows in set (0.00 sec)
Edit:2 case sensitive search added