MySQL: insert select in order - mysql

I want to insert data into a table in a specific order. This is because I need to give each entry a specific ID. What I am using is a select statement:
select (#i := #i + 1) as id, ...
order by column
The problem I am having is that this does not seem to work. I get the result I want from the select query. However, when I try to insert the data into the table the order by statement is ignored. Is there any way to force the correct order in the insert statement?
What I want is this:
+----+------+-------------+
| id | name | breadcrumbs |
+----+------+-------------+
| 1 | test | 01 |
| 5 | -d | 01,05 |
| 4 | c | 04 |
| 6 | e | 06 |
| 2 | -a | 06,02 |
| 3 | --b | 06,02,03 |
+----+------+-------------+
To become this:
+----+------+-------------+
| id | name | breadcrumbs |
+----+------+-------------+
| 1 | test | 01 |
| 2 | -d | 01,05 |
| 3 | c | 04 |
| 4 | e | 06 |
| 5 | -a | 06,02 |
| 6 | --b | 06,02,03 |
+----+------+-------------+
In a separate temporary table.

I would make certain that #i is initalised see select in from clause below
MariaDB [sandbox]> drop table if exists t;
Query OK, 0 rows affected (0.14 sec)
MariaDB [sandbox]>
MariaDB [sandbox]> create table t(id int, name varchar(10), breadcrumbs varchar(100));
Query OK, 0 rows affected (0.18 sec)
MariaDB [sandbox]> insert into t values
-> ( 1 , 'test' , '01' ),
-> ( 5 , '-d' , '01,05' ),
-> ( 4 , 'c' , '04' ),
-> ( 6 , 'e' , '06' ),
-> ( 2 , '-a' , '06,02' ),
-> ( 3 , '--b' , '06,02,03');
Query OK, 6 rows affected (0.01 sec)
Records: 6 Duplicates: 0 Warnings: 0
MariaDB [sandbox]>
MariaDB [sandbox]> drop table if exists t1;
Query OK, 0 rows affected (0.13 sec)
MariaDB [sandbox]> create table t1 as
-> select
-> #i:=#i+1 id,
-> t.name,t.breadcrumbs
-> from (select #i:=0) i,
-> t
-> order by breadcrumbs;
Query OK, 6 rows affected (0.22 sec)
Records: 6 Duplicates: 0 Warnings: 0
MariaDB [sandbox]>
MariaDB [sandbox]> select * from t1;
+------+------+-------------+
| id | name | breadcrumbs |
+------+------+-------------+
| 1 | test | 01 |
| 2 | -d | 01,05 |
| 3 | c | 04 |
| 4 | e | 06 |
| 5 | -a | 06,02 |
| 6 | --b | 06,02,03 |
+------+------+-------------+
6 rows in set (0.00 sec)

I want to insert data into a table in a specific order.
There is no internal order to the records in a MySQL database table. Tables are modeled after unordered sets. The only order which exists is the one you apply by using an ORDER BY clause when you query. So moving forward, instead of worrying about the order in which your records are inserted, you should instead make sure that your table has the necessary columns and data to order your result sets the way you want.

Related

MySQL dynamically display distinct values from a column with count of occurrences?

Using MySQL 5.5.34 on MAMP.
How do I display distinct values with count of occurrences ?
my_table looks like this:
id fruit
01 apple
02 orange
03 grape
04 apple
05 banana
06 orange
What i'm trying to display is something like:
apple 2
banana 1
grape 1
orange 2
fruits 6
I could hard code the values and use count with distinct but I'm sure there is a dynamic way. I've found some examples on here using group by and with rollup, but I can't seem to get the syntax right or find a example.
The non-dynamic way I'm doing right now:
SELECT fruit,COUNT(*) as count
FROM my_table
GROUP BY fruit
ORDER BY fruit ASC
WITH ROLLUP;
I hope somebody has some a clear example. I've been trying for many hours now. thanks!
You need to make the rollup row say fruits instead of NULL using the IFNULL() function
You also don't need ORDER BY
PROPOSED QUERY
SELECT IFNULL(fruit,'fruits') fruit,COUNT(*) as count
FROM my_table
GROUP BY fruit
WITH ROLLUP;
SAMPLE DATA
mysql> drop database if exists fruitdb;
Query OK, 0 rows affected (0.00 sec)
mysql> create database fruitdb;
Query OK, 1 row affected (0.00 sec)
mysql> use fruitdb
Database changed
mysql> create table my_table
-> (id int not null auto_increment,
-> fruit varchar(20) not null,
-> primary key (id));
Query OK, 0 rows affected (0.02 sec)
mysql> insert into my_table (fruit) values
-> ('apple'),('orange'),('grape'),
-> ('apple'),('banana'),('orange');
Query OK, 6 rows affected (0.00 sec)
Records: 6 Duplicates: 0 Warnings: 0
mysql> select * from my_table;
+----+--------+
| id | fruit |
+----+--------+
| 1 | apple |
| 2 | orange |
| 3 | grape |
| 4 | apple |
| 5 | banana |
| 6 | orange |
+----+--------+
6 rows in set (0.00 sec)
mysql>
PROPOSED QUERY EXECUTED
mysql> SELECT IFNULL(fruit,'fruits') fruit,COUNT(*) as count
-> FROM my_table
-> GROUP BY fruit
-> WITH ROLLUP;
+--------+-------+
| fruit | count |
+--------+-------+
| apple | 2 |
| banana | 1 |
| grape | 1 |
| orange | 2 |
| fruits | 6 |
+--------+-------+
5 rows in set, 1 warning (0.00 sec)
mysql>
GIVE IT A TRY !!!

How to remove certain strings from rows in MySQL

I am attempting to clean up in a messy table consisting of words which are unnecessary.
The example below shows the typical content:
row1 |
-------------
text <12> |
more [dada] |
(123) foo |
la {55w} da |
Basically what i define as unnecessary content is all the words starting and ending with a particular symbol: <...>, [...], {...} and (...). Usually i would use the replace function, but since the data inside of the symbols are arbitrary it is not quite possible.
Is it possible to use some kind of RegEX in the REPLACE function?
UPDATE
Please take notice that the content wrapped inside the symbols can any letters and numbers, basically unpredictable.
Ok i see now !
use the replace like this - see example(will clean everything from inside '()')
mysql> CREATE TABLE tbl (
-> txt VARCHAR(255)
-> );
Query OK, 0 rows affected (0.50 sec)
mysql> INSERT INTO tbl VALUES
-> ('sometext (asdebtrw)'),
-> ('some other text ( sd sdasddebtrw)'),
-> ('somesdaftext ( (sd)( ))ebt rw)()'),
-> ('sometext1'),
-> ('sometext2'),
-> ('sometext1 (replacethistext) anothertext1'),
-> ('s'),
-> ('w(sdf) rr')
-> ;
Query OK, 8 rows affected (0.00 sec)
Records: 8 Duplicates: 0 Warnings: 0
mysql> select * from tbl;
+------------------------------------------+
| txt |
+------------------------------------------+
| sometext (asdebtrw) |
| some other text ( sd sdasddebtrw) |
| somesdaftext ( (sd)( ))ebt rw)() |
| sometext1 |
| sometext2 |
| sometext1 (replacethistext) anothertext1 |
| s |
| w(sdf) rr |
+------------------------------------------+
8 rows in set (0.00 sec)
mysql> UPDATE tbl
-> SET txt = REPLACE(txt, SUBSTRING(txt, LOCATE('(', txt), LENGTH(txt) - LOCATE(')', REVERSE(txt)) - LOCATE('(', txt) + 2), '')
-> WHERE txt LIKE '%(%)%';
Query OK, 5 rows affected (0.20 sec)
Rows matched: 5 Changed: 5 Warnings: 0
mysql> select * from tbl;
+-------------------------+
| txt |
+-------------------------+
| sometext |
| some other text |
| somesdaftext |
| sometext1 |
| sometext2 |
| sometext1 anothertext1 |
| s |
| w rr |
+-------------------------+
8 rows in set (0.22 sec)
regex_replace is your mate here:
SELECT REGEXP_REPLACE('ab12cd','[0-9]','') AS remove_digits;
-> abcd
Though it may be a MariaDB enhancement.

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 create an empty VIEW in mySQL

I am trying to create an empty VIEW in mySQL with the columns I define.
i.e. I would like a view with columns: age, id, gender, but with 0 rows.
Thanks in advance.
Here's an example for you:
mysql> create or replace view v_test as
-> select 99 as age,
-> 2147483647 as id,
-> 'F' as gender
-> from dual
-> where false;
Query OK, 0 rows affected (0.04 sec)
mysql> desc v_test;
+--------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------+------+-----+---------+-------+
| age | int(2) | NO | | 0 | |
| id | bigint(10) | NO | | 0 | |
| gender | varchar(1) | NO | | | |
+--------+------------+------+-----+---------+-------+
3 rows in set (0.01 sec)
mysql> select * from v_test;
Empty set (0.00 sec)
Why you would ever want to do this is beyond me:
CREATE VIEW foo AS SELECT NULL AS age, NULL AS id, NULL AS gender WHERE FALSE
Try defining your view from this select statement:
SELECT 5 as age, 10 as id, 'M' as gender
WHERE age = 0
This will give you the correct types for the columns

How to get one row as a result when querying two tables following FNF?

I have a MySQL database with a few tables. They look something like this -
The food table:
+----------+------------+--------------+
| username | date | food |
+----------+------------+--------------+
| test123 | 2012-09-16 | rice |
| test123 | 2012-09-16 | pizza |
| test123 | 2012-09-16 | french fries |
| test123 | 2012-09-16 | burger |
+----------+------------+--------------+
The main table:
+----------+------------+----------------+---------------+-------------+-------------+
| username | date | water_quantity | water_chilled | smoked_what | smoke_count |
+----------+------------+----------------+---------------+-------------+-------------+
| test123 | 2012-09-16 | 1 | no | cigarettes | 20 |
+----------+------------+----------------+---------------+-------------+-------------+
When I use the query SELECT * FROM main,food WHERE main.date=food.date;, I get four rows as a result. How would it be possible that I get the results in a single row? Ultimately, when I encode the results into JSON, I want it to look something like this -
[
{
"username":"test123",
"date":"2012-09-16",
"water_quantity":"1",
"water_chilled":"no",
"smoked_what":"cigarettes",
"smoke_count":"20",
{
"food":"rice",
"food":"pizza",
"food":"french fries",
"food":"burger",
},
}
]
or something similar to. I am a newbie to MySQL and databases in general and also to JSON.. Thanks in advance for the help.
select m.*, GROUP_CONCAT(food SEPARATOR ',') AS food FROM main m INNER JOIN food f ON f.username = m.username and f.date = m.date;
Of course you can change what fields you select to control the output but that will solve your duplication issue.
As for the nested list of foods within the result set, you can use GROUP_CONCAT
SEE: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat
I will see if I can recreate for demo
DEMO:
mysql> create table main (id INT NOT NULL AUTO_INCREMENT, username varchar(12) NOT NULL, date DATETIME, water_quality INT, water_chilled CHAR(3), smoked_what varchar(32), smoke_count INT, primary key (id));
Query OK, 0 rows affected (0.04 sec)
mysql> create table food (id INT NOT NULL AUTO_INCREMENT, username varchar(12) NOT NULL, date DATETIME, food varchar(32), primary key (id));
Query OK, 0 rows affected (0.04 sec)
mysql> insert into food VALUES (1,'test123','2012-09-16','rice'),(2,'test123','2012-09-16','pizza'),(3,'test123','2012-09-16','french fries'),(4,'test123','2012-09-16','burger');Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> insert into main VALUES (1, 'test123', '2012-09-16', 1, 'no', 'cigarettes', 20);
Query OK, 1 row affected (0.00 sec)
mysql> select m.*, GROUP_CONCAT(food SEPARATOR ',') AS food FROM main m INNER JOIN food f ON f.username = m.username and f.date = m.date;
+----+----------+---------------------+---------------+---------------+-------------+-------------+----------------------------------+
| id | username | date | water_quality | water_chilled | smoked_what | smoke_count | food |
+----+----------+---------------------+---------------+---------------+-------------+-------------+----------------------------------+
| 1 | test123 | 2012-09-16 00:00:00 | 1 | no | cigarettes | 20 | rice,pizza,french fries,burger |
+----+----------+---------------------+---------------+---------------+-------------+-------------+----------------------------------+
1 row in set (0.00 sec)
mysql>