I'm a beginner in SQL and I have some troubles with this request, which just can't be executed because it's too inefficient. Here it is, it just loads for hours (!)
SELECT my_db_client_total.email as EMAIL_TOTAL,
my_db_client_total.name, my_db_client_total.country
FROM my_db_client_total, my_db_client_pro
WHERE (my_db_client_total.email<>'' )
AND (my_db_client_total.country = '120')
AND (my_db_client_total.email IN (SELECT my_db_client_pro.email
FROM my_db_client_pro));
My tables are organised in this way :
Table 1 : Table 2 :
email email
name name
country country
The purpose of the request it to test my database, and to process a further request where I want to select email, name and country from Table 1 where table1.email is not in table2.
Sorry for my bad English, and for my level, as I said earlier, I'm a beginner and self-taught.
If anyone can help me or at least enlighten me, I'll be so thankful for your time.
EDIT: I didn't precisely know but I'm working with a table where there is 20 000+ rows.
Solved
This is your query (fixed up a bit with table aliases):
SELECT ct.email as EMAIL_TOTAL, ct.name, ct.country
FROM my_db_client_total ct
WHERE (ct.email <> '' ) AND
(ct.country = 120) AND
(ct.email IN (SELECT my_db_client_pro.email FROM my_db_client_pro));
(I am assuming that 120 is really an integer.)
In older versions of MySQL, exists is more efficient than in, so rewrite the query as:
SELECT ct.email as EMAIL_TOTAL, ct.name, ct.country
FROM my_db_client_total ct
WHERE (ct.email <> '' ) AND
(ct.country = 120) AND
EXISTS (SELECT 1 FROM my_db_client_pro cp WHERE cp.email = ct.email);
Next, consider indexes. For this query, good indexes are:
create index idx_my_db_client_total_2 on my_db_client_total(country, email, name);
create index idx_my_db_client_pro_email on my_db_client_pro(email);
Your question states you are using MySQL, so this will give you an inner (record must exist in both tables) join.
SELECT my_db_client_total.email as EMAIL_TOTAL, my_db_client_total.name, my_db_client_total.country
FROM my_db_client_total inner join my_db_client_pro on my_db_client_pro.email = my_db_client_total.email
WHERE (my_db_client_total.email<>'' ) AND (my_db_client_total.country = '120');
To select a row that does not exist in the other table do this:
SELECT my_db_client_total.email as EMAIL_TOTAL, my_db_client_total.name, my_db_client_total.country
FROM my_db_client_total LEFT OUTER JOIN my_db_client_pro on my_db_client_pro.email = my_db_client_total.email
WHERE (my_db_client_total.email<>'' ) AND (my_db_client_total.country = '120') AND my_db_client_pro.email IS NULL;
You should be using a Join.
Check them out here: https://technet.microsoft.com/en-us/library/ms191472(v=sql.105).aspx
Example code:
SELECT my_db_client_total.email as EMAIL_TOTAL, my_db_client_total.name, my_db_client_total.country
FROM my_db_client_total AS ct
CROSS JOIN my_db_client_pro AS cp
ON ct.CLIENT_ID = cp.CLIENT_ID
SELECT my_db_client_total.email as EMAIL_TOTAL,
my_db_client_total.name, my_db_client_total.country
FROM
my_db_client_total,
WHERE (my_db_client_total.email <> '')
AND (my_db_client_total.country = '120')
AND (my_db_client_total.email not IN (SELECT my_db_client_pro.email
FROM my_db_client_pro));
Basically get all the data from table and on where condition getting the email address not in table 2
If you join the 2 tables, why don't you use the right side table in your query instead of making a subquery on it?
Try this (only the join) :
SELECT my_db_client_total.email as EMAIL_TOTAL, my_db_client_total.name, my_db_client_total.country
FROM my_db_client_total, my_db_client_pro
WHERE my_db_client_total.email <> ''
AND my_db_client_total.country = '120'
AND my_db_client_total.email = my_db_client_pro.email;
or this (only the subquery) :
SELECT my_db_client_total.email as EMAIL_TOTAL, my_db_client_total.name, my_db_client_total.country
FROM my_db_client_total
WHERE my_db_client_total.email <> ''
AND my_db_client_total.country = '120'
AND my_db_client_total.email IN (SELECT my_db_client_pro.email FROM my_db_client_pro);
Comments
Post a Comment