Here is the query you need:
SELECT name FROM
(
SELECT name FROM table1
UNION
SELECT name FROM table2
) A;
Here is some sample code based on your question:
use test
drop table if exists table1;
drop table if exists table2;
create table table1
(
id int not null auto_increment,
name varchar(10),
primary key (id)
);
create table table2 like table1;
insert into table1 (name) values ('A'),('B'),('C');
insert into table2 (name) values ('C'),('D'),('E');
SELECT name FROM
(
SELECT name FROM table1
UNION
SELECT name FROM table2
) A;
Here is the execution of that sample code:
mysql> drop table if exists table1;
Query OK, 0 rows affected (0.03 sec)
mysql> drop table if exists table2;
Query OK, 0 rows affected (0.03 sec)
mysql> create table table1 (
-> id int not null auto_increment,
-> name varchar(10),
-> primary key (id)
-> );
Query OK, 0 rows affected (0.05 sec)
mysql> create table table2 like table1;
Query OK, 0 rows affected (0.06 sec)
mysql> insert into table1 (name) values ('A'),('B'),('C');
Query OK, 3 rows affected (0.06 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> insert into table2 (name) values ('C'),('D'),('E');
Query OK, 3 rows affected (0.11 sec)
Records: 3 Duplicates: 0 Warnings: 0
mysql> SELECT name FROM (SELECT name FROM table1
-> UNION SELECT name FROM table2) A;
+------+
| name |
+------+
| A |
| B |
| C |
| D |
| E |
+------+
5 rows in set (0.00 sec)
mysql>
Give it a Try !!!
I think that better indexes for these queries are these (which you don't have on the tables now): (player_id, day_id)
and (target_id, day_id)
The optimizer choosing different indexes in the two situations has probably to due with table sizes and selectivity of the available indexes. I suggest you add the two indexes above and check (and compare) the new execution plans and timings with the old ones.
Update For InnoDB tables, the (target_id)
and (target_id, day_id)
indexes should be equivalent as all non clustered indexes also include the columns of the clustered index. It could be a blind spot on the optimizer, not identifying that the (target_id)
index can be used as if it was a (target_id, day_id)
index. But seeing that the similar index in the first case is chosen, the problem must be somewhere else.
And it is: PicPcrHistory.target_id
is of type varchar(36)
and so is Pictures.id
But one has utf8
and the other latin1
charset. So, there is your problem and why the index is not used. The two columns that are joined are not identical (type and charset.)
Change the charset of either one to match the other charset and the index will be used.
There are also other ways to write the queries - which appear to be of the [greatest-n-per-group]
type:
Using a derived table:
SELECT p.id,
p.pcr_score + 0.5 * COALESCE(h1.total,0) AS pcr_score
FROM
fpme_lua.Pictures AS p
JOIN
fpme_lua.PicPcrHistory AS h1
ON h1.target_id = p.id
JOIN
( SELECT hh.target_id,
Max(hh.day_id) AS day_id
FROM fpme_lua.PicPcrHistory AS hh
WHERE hh.day_id <= 15786
GROUP BY hh.target_id
) AS h2
ON h2.target_id = h1.target_id
AND h2.day_id = h1.day_id ;
Using a correlated subquery for the join condition (this is similar to the queries you have):
SELECT p.id,
p.pcr_score + 0.5 * COALESCE(h1.total,0) AS pcr_score
FROM
fpme_lua.Pictures AS p
JOIN
fpme_lua.PicPcrHistory AS h1
ON h1.target_id = p.id
AND h1.day_id =
( SELECT hh.day_id
FROM fpme_lua.PicPcrHistory AS hh
WHERE hh.target_id = p.id
AND hh.day_id <= 15786
ORDER BY hh.target_id DESC
LIMIT 1
) ;
And index on (target_id, day_id, total)
will be even better for the last query.
Best Answer
PROPOSED QUERY
SAMPLE DATA
SAMPLE DATA LOADED
PROPOSED QUERY EXECUTED
GIVE IT A TRY !!!