sql, multiple instances of the same table in FROM - mysql

Let's say I have a table named "mytable01". When I want to have two instances of the table in the query I do this:
SELECT t1.column, t2.column
FROM mytable01 t1, mytable01 t2;
Now, there are times that I want two instances from the same nested SELECT. Is there a way to do it without having to write it two times?

No! You want to do a self-join (joining the table with itself) you must to declare it each time. By the way try to avoid write queries in implicit format and use explicit join pattern like it:
select t1.column, t2.column
from table t1
join table t2 on t2.id = t1.parentid
btw again, you example missed the columns for the join and that ill force a cross join.

Related

JOIN with a query that returns a query

Some SELECT statements stores in table as a field. I need to write SELECT statement that joins with some SELECT that returns SELECT.
For example:
SELECT *
FROM table1
JOIN (SELECT t_select FROM table2 WHERE = 'some_condition')
Last SELECT SELECT t_select FROM table2 returns some SELECT statement as text.
I need to join table1 with the result of the query that stores in t_select
Do I understand? Basically, you want to "evaluate" the SELECT that is stored in the table? That seems like a really poor design to me.
If you really need to do this, you'll need to pull the SELECT statement out yourself, and send it as a second query. You can't do this in pure MySQL.
Do you just want a subquery?
SELECT *
FROM table1 t1 JOIN
(SELECT t2.* FROM table2 t2 WHERE = 'some_condition') t2
on t1.<somecol> = t2.<someothercol>;
All in all you can't execute the query that is stored in the table withing another query. You will have to retrieve the query first, prepare it, and then execute it. Have a look at execute immediate :
http://dev.mysql.com/worklog/task/?id=2793
http://www.postgresql.org/docs/9.1/static/ecpg-sql-execute-immediate.html
Storing sql statements in a table is not very common, and there's usually better ways to do it.

Does mysql optimize the IN clause

When i execute this mysql query like
select * from t1 where colomn1 in (select colomn1 from t2) ,
what really happens?
I want to know if it executes the inner statement for every row?
PS: I have 300,000 rows in t1 and 50,000 rows in t2 and it is taking a hell of a time.
I'm flabbergasted to see that everyone points out to use JOIN as if it is the same thing. IT IS NOT!, not with the information given here. E.g. What if t2.column1 has doubles ?
=> Assuming there are no doubles in t2.column1, then yes, put a UNIQUE INDEX on said column and use a JOIN construction as it is more readable and easier to maintain. If it is going to be faster; that depends on what the query engine makes from it. In MSSQL the query-optimizer (probably) would consider them the same thing; maybe MySQL is 'not so eager' to recognize this... don't know.
=> Assuming there can be doubles in t2.column1, put a (non-unique) INDEX on said column and rewrite the WHERE IN (SELECT ..) into a WHERE EXISTS ( SELECT * FROM t2 WHERE t2.column1 = t1.column1). Again, mostly for readability and ease of maintenance; most likely the query engine will treat them the same...
The things to remember are
Always make sure you have proper indexing (but don't go overboard)
Always realize that what really happens will be an interpretation of your sql-code; not a 'direct translation'. You can write the same functionality in different ways to achieve the same goal. And some of these are indeed more resilient to different scenarios.
If you only have 10 rows, pretty much everything works. If you have 10M rows it could be worth examining the query plan... which most-likely will be different from the one with 10 rows.
A join would be quicker, viz:
select t1.* from t1 INNER JOIN t2 on t1.colomn1=t2.colomn1
Try with INNER JOIN
SELECT t1.*
FROM t1
INNER JOIN t2 ON t1.column1=t2.column1
You should do indexing in column1 and then you can use inner join
for indexing
CREATE INDEX index1 ON t1 (col1);
CREATE INDEX index2 ON t2 (col2);
select t1.* from t1 INNER JOIN t2 on t1.colomn1=t2.colomn1

How to make SQL query faster?

I have big DB. It's about 1 mln strings. I need to do something like this:
select * from t1 WHERE id1 NOT IN (SELECT id2 FROM t2)
But it works very slow. I know that I can do it using "JOIN" syntax, but I can't understand how.
Try this way:
select *
from t1
left join t2 on t1.id1 = t2.id
where t2.id is null
First of all you should optimize your indexes in both tables, and after that you should use join
There are different ways a dbms can deal with this task:
It can select id2 from t2 and then select all t1 where id1 is not in that set. You suggest this using the IN clause.
It can select record by record from t1 and look for each record if it finds a match in t2. You would suggest this using the EXISTS clause.
You can outer join the table then throw away all matches and stay with the non-matching entries. This may look like a bad way, especially when there are many matches, because you would get big intermediate data and then throw most of it away. However, depending on how the dbms works, it can be rather fast, for example when it applies hash join techniques.
It all depends on table sizes, number of matches, indexes, etc. and on what the dbms makes of your query. There are dbms that are able to completely re-write your query to find the best execution plan.
Having said all this, you can just try different things:
the IN clause with (SELECT DISTINCT id2 FROM t2). DISTINCT can reduce the intermediate result significantly and really speed up your query. (But maybe your dbms does that anyhow to get a good execution plan.)
use an EXISTS clause and see if that is faster
the outer join suggested by Parado

Are there any differences in the following sql statements?

SELECT * FROM table t
SELECT t.* FROM table t
I tried it and it yielded the same results, but I want to make sure because I'm refactoring a piece of code that uses the second version, and I was surprised as it is both longer to write, and less simple.
Are there any hidden stuff here?
MySQL version: 5.5.29-0ubuntu0.12.04.2 (Ubuntu)
Both statements are the same in your case.
They would be not if you join multiple tables in one query.
select *
selects all columns.
select t.*
select all columns of table t (or the table assigned the alias t)
SELECT * FROM table t and SELECT t.* FROM table t
Return the whole table
SELECT t.* FROM table as t inner join table2 as t2
will only return the fields in the "table" table while
SELECT * FROM table as t inner join table2 as t2
will return the fields of table and table2
Both the statements will give same results until it's combined with another table with some table operator as Join, Apply where you will need to uniquely identify columns( more specifically ambiguous columns ) from this table.
As a best practice you should use column names instead of using select * as it makes code more readable and front end code doesn't break in case table structure gets changed at any point of time.
The statements are identical. All you have is an alias for table "table" called "t".
SELECT * will return all columns from all tables in the query. SELECT t.* will return all columns from the table named, or aliased as, t. The same in your example because there's only one table involved.

mySQL UPDATE all columns from corresponding columns in another table

I have two tables with identical schema. And lots of columns!
I can update a record from the corresponding table by doing
update t1
join t2 on t2.id=t1.id
set t1.column1=t2.column1,
t1.column2=t2.column2...
where t2.columnx > 123;
But I have a ton of fields and am by nature, a lazy bastard who'd rather shave a yak and post on SE than type out a list of columns (possibly missing 1).
Other than some funky solution that writes out the column list to a text file etc, is there valid mySQL syntax that skips the explicit listing of all the columns and works more like INSERT...SELECT?
REPLACE INTO t1 SELECT * FROM t2 WHERE columnx>123;
Try to use REPLACE INTO ... SELECT ... syntax http://dev.mysql.com/doc/refman/5.0/en/replace.html
REPLACE INTO t1 SELECT t2.* FROM t2, t1 WHERE t1.columnx>123 AND t1.id=t2.id;
Warning! Not tested!
This code would work only if tables have unique indexes on id columns.