What does "USING table1, table1 as vtable" mean in MySQL? - mysql

I'm new to MySQL and I'm having a bit of trouble figuring out what this means:
DELETE from keywords USING keywords, keywords as vtable
WHERE (keywords.id > vtable.id) && (keywords.keyword=vtable.keyword)
Specifically, what does this part USING keywords, keywords as vtable mean?
Is there a better way to write this query that would be equivalent? I've read that creating virtual tables isn't efficient.
Also, is the . separating the table and the column?

vtable is an alias for the keywords table so that it can be self-joined. No different from any alias, but selection of the specific alias vtable may have led you to believe that there is some special virtual table mechanism involved. There isn't.
From an efficiency standpoint, this looks like a normal use of a self-join. It should be reasonably efficient, if there are indexes on the id and perhaps keywords field.
Also the dot ., does indeed separate table and column name (or table alias and column name).
Here's the same query with a different alias name:
DELETE from keywords
USING keywords, keywords as k2
WHERE (keywords.id > k2.id) && (keywords.keyword=k2.keyword)
And here's the whole query done a little differently, but maybe less confusingly, with a JOIN:
DELETE keywords
FROM keywords
INNER JOIN keywords as k2 ON keywords.keyword = k2.keyword
WHERE keywords.id > k2.id

This is a very fabulous method of query as whenever you got stuck in a condition such that you want to manipulate in a table by comparing itself from a record of same table.
The USING keyword can use a list of columns that appear in both tables and is equivalent to saying C.ID = O.ID AND S.ID = O.ID.
mysql>
mysql> CREATE TABLE Employee(
-> id int,
-> first_name VARCHAR(15),
-> last_name VARCHAR(15),
-> start_date DATE,
-> end_date DATE,
-> salary FLOAT(8,2),
-> city VARCHAR(10),
-> description VARCHAR(15)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql>
mysql> create table job (
-> id int,
-> title VARCHAR(20)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql>
mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, salary, City, Description)
-> values (1,'Jason', 'Martin', '19960725', '20060725', 1234.56, 'Toronto', 'Programmer');
Query OK, 1 row affected (0.02 sec)
mysql>
mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, salary, City, Description)
-> values(2,'Alison', 'Mathews', '19760321', '19860221', 6661.78, 'Vancouver','Tester');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, salary, City, Description)
-> values(3,'James', 'Smith', '19781212', '19900315', 6544.78, 'Vancouver','Tester');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, salary, City, Description)
-> values(4,'Celia', 'Rice', '19821024', '19990421', 2344.78, 'Vancouver','Manager');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, salary, City, Description)
-> values(5,'Robert', 'Black', '19840115', '19980808', 2334.78, 'Vancouver','Tester');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, salary, City, Description)
-> values(6,'Linda', 'Green', '19870730', '19960104', 4322.78,'New York', 'Tester');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, salary, City, Description)
-> values(7,'David', 'Larry', '19901231', '19980212', 7897.78,'New York', 'Manager');
Query OK, 1 row affected (0.02 sec)
mysql>
mysql> insert into Employee(id,first_name, last_name, start_date, end_Date, salary, City, Description)
-> values(8,'James', 'Cat', '19960917', '20020415', 1232.78,'Vancouver', 'Tester');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> insert into job (id, title) values (1,'Tester');
Query OK, 1 row affected (0.01 sec)
mysql> insert into job (id, title) values (2,'Accountant');
Query OK, 1 row affected (0.00 sec)
mysql> insert into job (id, title) values (3,'Developer');
Query OK, 1 row affected (0.00 sec)
mysql> insert into job (id, title) values (4,'Coder');
Query OK, 1 row affected (0.00 sec)
mysql> insert into job (id, title) values (5,'Director');
Query OK, 1 row affected (0.00 sec)
mysql> insert into job (id, title) values (6,'Mediator');
Query OK, 1 row affected (0.00 sec)
mysql> insert into job (id, title) values (7,'Proffessor');
Query OK, 1 row affected (0.00 sec)
mysql> insert into job (id, title) values (8,'Programmer');
Query OK, 1 row affected (0.01 sec)
mysql> insert into job (id, title) values (9,'Developer');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> select * from job;
+------+------------+
| id | title |
+------+------------+
| 1 | Tester |
| 2 | Accountant |
| 3 | Developer |
| 4 | Coder |
| 5 | Director |
| 6 | Mediator |
| 7 | Proffessor |
| 8 | Programmer |
| 9 | Developer |
+------+------------+
9 rows in set (0.00 sec)
mysql> select * from Employee;
+------+------------+-----------+------------+------------+---------+-----------+-------------+
| id | first_name | last_name | start_date | end_date | salary | city | description |
+------+------------+-----------+------------+------------+---------+-----------+-------------+
| 1 | Jason | Martin | 1996-07-25 | 2006-07-25 | 1234.56 | Toronto | Programmer |
| 2 | Alison | Mathews | 1976-03-21 | 1986-02-21 | 6661.78 | Vancouver | Tester |
| 3 | James | Smith | 1978-12-12 | 1990-03-15 | 6544.78 | Vancouver | Tester |
| 4 | Celia | Rice | 1982-10-24 | 1999-04-21 | 2344.78 | Vancouver | Manager |
| 5 | Robert | Black | 1984-01-15 | 1998-08-08 | 2334.78 | Vancouver | Tester |
| 6 | Linda | Green | 1987-07-30 | 1996-01-04 | 4322.78 | New York | Tester |
| 7 | David | Larry | 1990-12-31 | 1998-02-12 | 7897.78 | New York | Manager |
| 8 | James | Cat | 1996-09-17 | 2002-04-15 | 1232.78 | Vancouver | Tester |
+------+------------+-----------+------------+------------+---------+-----------+-------------+
8 rows in set (0.00 sec)
mysql>
mysql>
mysql>
The syntax looks like the following:
mysql>
mysql> SELECT C.First_Name, C.Last_Name, O.title
-> FROM Employee AS C
-> LEFT JOIN job as O USING (ID);
+------------+-----------+------------+
| First_Name | Last_Name | title |
+------------+-----------+------------+
| Jason | Martin | Tester |
| Alison | Mathews | Accountant |
| James | Smith | Developer |
| Celia | Rice | Coder |
| Robert | Black | Director |
| Linda | Green | Mediator |
| David | Larry | Proffessor |
| James | Cat | Programmer |
+------------+-----------+------------+
8 rows in set (0.00 sec)
mysql>
mysql>
mysql>
mysql> drop table job;
Query OK, 0 rows affected (0.00 sec)
mysql> drop table Employee;
Query OK, 0 rows affected (0.01 sec)
mysql>
mysql>
In this example, the USING keyword would be like using the ON keyword with C.ID = O.ID following it.
This is another shortcut to save time.
mysql>

Related

Search for a text containing backslash in MySQL

I have a mysql table with 2 entries (id ,title) (int, text)
A row of dummy data in the table looks like
id title
1 apple\"apple
My query intends to do a search on the field title
select * from table1 where title='apple\"apple';
I also tried using
select * from table1 where title like('apple\"apple');
The above query did not seem to work as well.
Both queries are returning an empty sets. Is it not possible to search for a string that has backslash in it?
PS :: The \ is added to the DB as part of escaping the double quotes.
Sure? It works as expected.
mysql> CREATE TABLE MyTbl (id INT, title TEXT);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO MyTbl VALUES(1,'apple "apple');
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM MyTbl;
+------+-------------+
| id | title |
+------+-------------+
| 1 | apple"apple |
+------+-------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM MyTbl WHERE title = 'apple \"apple';
+------+-------------+
| id | title |
+------+-------------+
| 1 | apple"apple |
+------+-------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM MyTbl WHERE title like('apple \"apple');
+------+-------------+
| id | title |
+------+-------------+
| 1 | apple"apple |
+------+-------------+
1 row in set (0.00 sec)
Maybe Is it something related to the space character?
mysql> SELECT * FROM MyTbl WHERE title = 'apple\"apple';
Empty set (0.00 sec)
mysql> SELECT * FROM MyTbl WHERE title = 'apple \"apple';
+------+--------------+
| id | title |
+------+--------------+
| 1 | apple "apple |
+------+--------------+
1 row in set (0.00 sec)
What about running this command? What It returns for you?
mysql> SELECT #NO_BACKSLASH_ESCAPES;
+----------------------------------------------+
| #NO_BACKSLASH_ESCAPES |
+----------------------------------------------+
| NULL |
+----------------------------------------------+
1 row in set (0.00 sec)

is it possible to stop auto increment in mysql for particular record and store duplicate number

i want to insert a duplicated value into table which have auto_increamented colum.
can i insert like this
auto_incremet
+---------------+---------
| invoiceNumber | totalAmt |
+---------------+----------+
| 1 | 200 |
| 0 158
| 2 | 1200 |
| 0 122 |
| 3 65 |
| 4 | 240 |
| 5 | 330 |
| 6 | 80 |
+---------------+---------
i do not want to increment the value for particular record .
is it possible to do so?
it is possible with additional table so that i can send particular records to other table and stop it increment in first table.
but cant it be done with same table ?
Yes, but it can't be 0. It could be 1, though.
MariaDB [wow]> create table test ( id int(11) not null auto_increment, name varchar(15), key id (id));
Query OK, 0 rows affected (0.02 sec)
MariaDB [wow]> insert into test (id, name) values (1, 'mark');
Query OK, 1 row affected (0.00 sec)
MariaDB [wow]> insert into test (id, name) values (0, 'allan');
Query OK, 1 row affected (0.01 sec)
MariaDB [wow]> insert into test (id, name) values (1, 'patrick');
Query OK, 1 row affected (0.00 sec)
MariaDB [wow]> insert into test (name) values ('chris');
Query OK, 1 row affected (0.00 sec)
MariaDB [wow]> insert into test (name) values ('oliver');
Query OK, 1 row affected (0.00 sec)
MariaDB [wow]> insert into test (id, name) values (1, 'damien');
Query OK, 1 row affected (0.00 sec)
Observe:
MariaDB [wow]> select * from test;
+----+---------+
| id | name |
+----+---------+
| 1 | mark |
| 2 | allan |
| 1 | patrick |
| 3 | chris |
| 4 | oliver |
| 1 | damien |
+----+---------+
Obviously this is not a very good idea. Create a second column and call it invoice_id. Increment it using a sequence table.
But yes, to answer the question, although auto_increment must be on a key, it does not need to be on a UNIQUE key such as the primary key.

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 !!!

SELECT… INSERT with NOT NULL fields

I am trying to do a SELECT... INSERT into a table with constraints that prevent NULL values:
mysql> create table if not exists table1 (
-> id int not null auto_increment,
-> description varchar(45),
-> primary key (`id`)
-> );
Query OK, 0 rows affected (0.01 sec)
mysql> create table if not exists table2 (
-> id int not null auto_increment,
-> description varchar(45) not null,
-> primary key (`id`),
-> unique index `unique_desc` (`description`)
-> );
Query OK, 0 rows affected (0.02 sec)
mysql> insert ignore into table1
-> (description)
-> values("stupid thing"),
-> ("another thing"),
-> (null),
-> ("stupid thing"),
-> ("last thing");
Query OK, 5 rows affected (0.00 sec)
Records: 5 Duplicates: 0 Warnings: 0
mysql> select * from table1;
+----+---------------+
| id | description |
+----+---------------+
| 1 | stupid thing |
| 2 | another thing |
| 3 | NULL |
| 4 | stupid thing |
| 5 | last thing |
+----+---------------+
5 rows in set (0.00 sec)
Cool, we have the source (table1) and destination (table2) tables created, and the source table populated with some duplicate, null data.
If I do a normal SELECT... INSERT into the destination table, I get a column with empty string as the value:
mysql> insert ignore into table2
-> (description)
-> select description
-> from table1;
Query OK, 4 rows affected, 1 warning (0.00 sec)
Records: 5 Duplicates: 1 Warnings: 1
mysql> select * from table2;
+----+---------------+
| id | description |
+----+---------------+
| 3 | |
| 2 | another thing |
| 4 | last thing |
| 1 | stupid thing |
+----+---------------+
4 rows in set (0.00 sec)
This is bad. But some boss brogrammer led me to the answer in this question:
MySQL Insert Select - NOT NULL fields
And now this method gives me the desired result:
mysql> insert ignore into table2
-> (description)
-> select description
-> from table1
-> where description <> '' and description is not null;
Query OK, 3 rows affected (0.00 sec)
Records: 4 Duplicates: 1 Warnings: 0
mysql> select * from table2;
+----+---------------+
| id | description |
+----+---------------+
| 2 | another thing |
| 3 | last thing |
| 1 | stupid thing |
+----+---------------+
3 rows in set (0.00 sec)
Is there a way for me to get the above result without having to manually protect each field using the WHERE clause?
Thanks in advance,
K
This technically answers your question in that you can eliminate the nulls by a join instead of the where clause.
insert ignore into table2
(description)
select t.description from table1 t
join
(
select distinct description from table1
) t1 on (t.description=t1.description);
I am pretty sure, however, that you will need to specify a join for each field though. Off the top of my head, I can't think of a way around this.

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)