MYSQL unable to load OR operator on different tables - php

I think nothing wrong with my query, but don't know why system becomes very slow when I load this code in phpmyadmin. Any advice please help.
select
*
from
`table1`
left join
`table2`
on
table1.id = table2.id
where
(
(table1.email = 'test#test.com' and table1.mobile = '99999999')
or
(table2.email = 'test#test.com' and table2.mobile = '99999999')
)
Thanks in advance.

Add this to each table:
INDEX(email, mobile) -- in either order.
If that does not speed it up enough, then also turn the OR into a UNION:
SELECT *
FROM ( ( SELECT id FROM table1 WHERE email = ... AND mobile = ... )
UNION DISTINCT
( SELECT id FROM table2 WHERE email = ... AND mobile = ... )
) AS x
JOIN table1 WHERE table1.id = x.id
JOIN table2 WHERE table2.id = x.id

Add these indexes:
ALTER TABLE `table1` ADD INDEX `table1_idx_id` (`id`);
ALTER TABLE `table2` ADD INDEX `table2_idx_id` (`id`);
ALTER TABLE `table1` ADD INDEX `table1_idx_email_mobile_id` (`email`, `mobile`, `id`);
ALTER TABLE `table2` ADD INDEX `table2_idx_email_mobile_id` (`email`, `mobile`, `id`);
And the transformed query (avoiding the OR condition, which is not indexable, by using UNION DISTINCT):
(SELECT
*
FROM
`table1`
LEFT JOIN
`table2` ON table1.id = table2.id
WHERE
((table2.email = 'test#test.com'
AND table2.mobile = '99999999'))) UNION DISTINCT (SELECT
*
FROM
`table1`
LEFT JOIN
`table2` ON table1.id = table2.id
WHERE
((table1.email = 'test#test.com'
AND table1.mobile = '99999999')))
P.S, if there is no option to have duplicates, use UNION ALL instead of UNION DISTINCT, as it should perform better (avoid the duplicates elimination, which can take time).

Related

How to check id of one table to another table?

How to find whether distinct value id of one table exits to another tables or not using php.
For example: Let table1 have id (not primary or unique) 4, 5, 6, 4, 6, how to check if id of table2 have 4, 5, 6 or not ?
$query_check= "select distinct(project_code) from table1";
$projects_check = mysql_query($query_check);
while ($result_check = mysql_fetch_array($projects_check)){
$all[] = $result_check[0];
}
$query = "select id from table2";
$projects = mysql_query($query);
while ($result = mysql_fetch_array($projects)){
foreach($all as $all_val){
$pro_code = $result[0];
if($pro_code != $all_val){ }
}
}
This SQL may help:
SELECT table2.id
FROM table2
WHERE table2.id NOT IN (
SELECT DISTINCT table1.id
FROM table1
)
SELECT table2.id
FROM table2
WHERE table2.id IN (
SELECT DISTINCT table1.id
FROM table1
)
To get a list of all the project codes from table1 that are ids in table2:-
SELECT DISTINCT table1.project_code
FROM table1
INNER JOIN table2
ON table1.project_code = table2.id
To get a list of all the project codes from table1 that are NOT ids in table2
SELECT DISTINCT table1.project_code
FROM table1
LEFT OUTER JOIN table2
ON table1.project_code = table2.id
WHERE table2.id IS NULL
If it is the entries on 2 that you want that are not on 1
SELECT DISTINCT table2.id
FROM table2
LEFT OUTER JOIN table1
ON table1.project_code = table2.id
WHERE table1.project_code IS NULL

Join but return ALL records from Table

I have the following SQL query:
SELECT * FROM `table1` INNER JOIN `table2` ON table1.messageid=table2.messageid WHERE `venue_active` = 1
The above works fine but it only returns fields where both tables have a messageid field.
My problem is that I need it to return ALL fields from Table1 reguardless if it has a messageid match in table2 or not.
So, in other words I need ALL records to be returned from Table1 and all records from Table2 where there's a messageid that matches both.
How can I do this?
Use a LEFT JOIN rather
SELECT *
FROM `table1` LEFT JOIN
`table2` ON table1.messageid=table2.messageid
WHERE `venue_active` = 1
That said, it will only work if venue_active is also part of table1, and not table2.
Have a look at the different scenarios
SQL Fiddle DEMO
Use a LEFT join rather than INNER
For example:
SELECT * FROM `table1`
LEFT JOIN `table2` ON table1.messageid=table2.messageid
WHERE `venue_active` = 1
Either you need a LEFT JOIN instead, or
a FULL OUTER JOIN workaround for MySQL:
SELECT
a.*,
b.*
FROM
table1 a
LEFT JOIN
table2 b ON a.messageid = b.messageid
WHERE a.venue_active = 1
UNION
SELECT
a.*,
b.*
FROM
table1 a
RIGHT JOIN
table2 b ON a.messageid = b.messageid;
WHERE a.venue_active = 1

How to use table aliases with MYSQL UPDATE

I have to update a mysql table using PHP's mysql_query() function. Therefore I need to send the following UPDATE query in only one statement:
SET #i = 0;
UPDATE mytable SET id=(#i:=#i+1);
I have read some examples where this can be done with SELECT statements using table aliases like:
SELECT #rn:=#rn+1 AS rank, t1.* FROM (SELECT * FROM mytable) t1, (SELECT #rn:=0) t2
Is there some way to use these table aliases with the UPDATE statement that I need to use?
Edit:
Based on Topher Hunt's answer, I think I could create a copy of mytable using:
CREATE TABLE mytable_copy SELECT #rn:=#rn+1 AS id, t1.* FROM (SELECT * FROM mytable) t1, (SELECT #rn:=0) t2
Then DROP mytable and RENAME mytable_copy to mytable.
Would this statement create an exact copy of mytable, with the same field types and lenghts that the ones in mytable?
If you use JOINs between your tables, the syntax is very similar between SELECT and UPDATE statements. Example:
SELECT *
FROM table1 a
JOIN table2 b ON a.something = b.something ## (conditions for linking tables)
JOIN table3 c ON b.something = c.something
WHERE a.something = 'value'
A SELECT statement that joins 3 tables, can be turned around into an UPDATE statement just by removing the SELECT line, changing the word FROM to UPDATE, and adding a "SET" clause to say what you want to change. Like this:
UPDATE table1 a
JOIN table2 b ON a.something = b.something ## (conditions for linking tables)
JOIN table3 c ON b.something = c.something
SET a.variable = 'value2',
b.something = 'value3',
c.somethingelse = 'value4'
WHERE a.something = 'value';
You can make changes to lots of fields at the same time, if needed; just separate each SET item with commas.
Why not just drop this column and add a new column as a primary key with auto_increment? This will automatically assign the values you require.
ALTER TABLE mytable DROP COLUMN id;
ALTER TABLE mytable ADD ( id int AUTO_INCREMENT PRIMARY KEY );
-or- as you requested...
UPDATE mytable
JOIN (SELECT #xxx := 0) AS v1
SET id = (#xxx := #xxx + 1)
;

php select from where multi dual

I want to insert some data into database. During the insert, I want to make a judge first: if title not exist in table1 and table2, then insert. how to write this dual sentence? Is this right? OR... Thanks.
mysql_query("
INSERT INTO table1 title
SELECT '".$title."'
FROM dual
WHERE not exists (
SELECT title
FROM table1
WHERE table1.title = '".$title."'
) AND (
SELECT title
FROM table2
WHERE table2.title = '".$title."'
) ");
First of all, MySQL does not use the dual table. Just select the value directly. Normally to insert into a table, you only need to use either
INSERT INTO table1(title) SELECT 'something'; # or
INSERT INTO table1(title) VALUES ('something');
However, the below uses a made up table (aliased TT) to be able to use a LEFT JOIN on it to other tables.
mysql_query("
INSERT INTO table1(title)
SELECT theTitle
FROM (SELECT '".$title."' theTitle) TT
LEFT JOIN table1 ON table1.title = TT.theTitle
LEFT JOIN table2 ON table2.title = TT.theTitle
WHERE table1.title is null and table2.title is null
");
You can also just complete your NOT EXISTS clauses
mysql_query("
INSERT INTO table1(title)
SELECT '".$title."'
WHERE NOT EXISTS (SELECT * FROM table1 WHERE title = '".$title."')
AND NOT EXISTS (SELECT * FROM table2 WHERE title = '".$title."')
");
But I prefer the former, because this requires you to use $title 3 times.
mysql_query("INSERT INTO table1 title
SELECT '".$title."' FROM dual
WHERE not exists (SELECT title FROM table1 WHERE table1.title = '".$title."') AND
not exists (SELECT title FROM table2 WHERE table2.title = '".$title."') ");
missing second not exists in query.
Union anyone?
mysql_query("
INSERT INTO table1 title
SELECT '".addSlashes($title)."'
FROM dual
WHERE not exists (
SELECT title
FROM table1
WHERE title = '".addSlashes($title)."'
UNION
SELECT title
FROM table2
WHERE title = '".addSlashes($title)."'
) ");

How do I compare two tables data?

Hi I do have an old table and new table with same index/data. TABLE1 and TABLE2
but TABLE1 has got more data than TABLE2. this was maintained by some one and I dont know how this happened. so my question is how do I compare these two table and find which data is TABLE2 missing?? there is almost 200000 datas there so manually doing is not possible...
in PHP:
http://us.php.net/manual/en/function.array-diff.php
in SQL:
SELECT * FROM TABLE1 WHERE id {NOT} IN ( SELECT id FROM TABLE2 )
depending on criteria of comparison
Solution without nested query:
select TABLE1.id from TABLE1 left join TABLE2 on TABLE1.id = TABLE2.id where TABLE2.id is null
Did you mean something like this:
SELECT * FROM TABLE1 t1 WHERE NOT EXISTS(SELECT * FROM TABLE2 WHERE t1.id == t2.id)
By same index I am hoping you mean they share a primary key?
SELECT * FROM TABLE1 WHERE username NOT IN (SELECT username FROM TABLE2)

Categories