Select columns without using subquery in mysql - mysql

I want to select some records from table "A" but records that are not in table "B".
Example...
Tables are...
A{A_ID, A_Date, A_Price};
B{B_ID, A_ID};
I want to select records from table "A" with primary key A_ID but only those records that are not table "B" on joining both table on primary key A_ID.
I can do this with query...
select * from A where A_ID not in (select A_ID from B)
but my problem is subquery. Because it takes too much time run, if data quantity big.
SO I WANT TO RUN IT WITHOUT SUBQUERY.
please help!!!

Try these queries:
select * from TableA A
where not exists(select 1 from TableB where A_ID = A.A_ID)
or
select A.* from TableA A left join TableB B
on A.A_ID = B.A_ID
where B.B_ID is null

Related

MySql Join Issue When Join Two Tables

I have some doubt in MySQL joins
I have 2 tables for example TableA,TableB
TableA primary key is Foreign key of Table B
So I'm using inner join to get matched values but TableB have one column for row activate status so all active status is zero means I need to get that record or else I need to skip that record.
My query:.
Select * From TableA a inner join TableB b on a.id=b.aid where b.isActive=0;
The above query was return value if any one value is true
For example any one of is active row true. But I need to check all row is zero if it's all value zero means I need to return that so how I do that..?
Thanks in advance.
Select a.*
From TableA a
where not exists(SELECT 1 FROM TableB b WHERE a.id=b.aid AND b.isActive=1);
You can use your query change the filter as follows:
SELECT * FROM TableA a
JOIN TableB b ON a.id=b.aid
WHERE a.id NOT IN(SELECT aid FROM TableB WHERE isActive=1)

Check if table a primary key is exist in table b

Table A:
ID, Name, etc.
Table B:
ID, TableA-ID.
SELECT * FROM A;
and I want to return a boolean value in the same result for this condition ( if A.ID Exists in Table B).
There are several ways of achieving what you need. Below are three possibilities. These all differ in execution plans and how database actually wants to execute them so depending on your record count one may be more efficient than the other. It's better if you see it for yourself.
1) Use LEFT JOIN and check if a non-null field from B is not null to ensure the record exists. Then apply DISTINCT clause if relationship is 1:N to only show rows from A without duplicates.
select distinct a.*, b.id is not null as exists_b
from a
left join b on
a.id = b.tablea-id
2) Use exists() function, which will be evaluated for each row being returned from table A.
select a.*, exists(select 1 from b where a.id = b.tablea-id) as exists_b
from a
3) Use a combination of subquery expression EXISTS and it's contradiction in two queries to check if a record has or has not a match within table B. Then UNION ALL to combine both results into one.
select *, true as exists_b
from a
where exists (
select 1
from b
where a.id = b.tablea-id
)
union all
select *, false as exists_b
from a
where not exists (
select 1
from b
where a.id = b.tablea-id
)
select A.*, IFNULL((select 1 from B where B.TableA-ID = A.ID limit 1),0) as `exists` from A;
The above statement will result in a 1, if the key exists, and a 0 if that key does not exist. Limit 1 is important if there are multiple records in B

Delete rows from a table with not in ( another table )

I have two tables A and B, in the B there is a foreign key from A, what I want to do is to delete all the rows from A that they don't have an occurrence in B, I execute the following query but it's not working :
DELETE from A
WHERE id_A
not in (select DISTINCT(foreign_key_of_A_in_B) from B)
Any idea ?
My first recommendation is to try not exists rather than not in:
DELETE a FROM a
WHERE NOT EXISTS (SELECT 1 FROM b WHERE b.foreign_key_of_A_in_B = a.id_A);
NOT IN returns false or NULL if any value in the subquery is NULL. That is how the operator is defined. NOT EXISTS has more expected behavior. So, if you have any NULL values in the subquery, this will work (i.e. delete rows) but the NOT IN version will not.
I would recommend that you try the logic out using SELECT before doing a DELETE:
SELECT A.*
FROM A
WHERE NOT EXISTS (SELECT 1 FROM b WHERE b.foreign_key_of_A_in_B = A.id_A);
A standard for DELETE FROM table WHERE id NOT IN would look like this:
DELETE from Table_A
WHERE id -- ID of Table_A
not in (select ID FROM Table_B)
This should find the IDs not in Table A from Table B, as your question states
Try this in a SELECT statement first to see if it returns the correct rows:
SELECT * from Table_A
WHERE id -- ID of Table_A
not in (select ID FROM Table_B)
Don't forget to cross-reference some rows to double check.

delete records based on join result

I have two tables that are joined by an id.
Table A is where I define the records.
Table B is where I use the definition and add some data.
I am doing some data normalization and I have realized that on table B there are some ID that are no longer defined in table A.
If I run this query:
SELECT B.id_cred, A.id_cre from B LEFT JOIN A ON B.id_cred=A.id_cre
I see those records that are NULL on A.id_cre.
I'd like to DELETE from table B those records where the query returns null on table A?
Something like:
DELETE FROM B WHERE id IN (SELECT B.id from B LEFT JOIN A ON B.id_cred=A.id_cre WHERE a.id IS NULL)
but this query throws an error because table B is target and reference at the same time.
You can't specify target table B for UPDATE in FROM clause
Note that the join query will return 1408 rows so I need to do it in a massive way
Option 1, use NOT EXISTS:
delete from B
where not exists (select 1 from A where A.id_cre = B.id_cred)
Option 2, use a DELETE with JOIN:
delete B
from B
left join A on B.id_cred = A.id_cre
where A.id_cre is null
This should do the trick:
DELETE FROM B
WHERE NOT EXISTS (
SELECT id_cre
FROM A
WHERE B.id_cred=A.id_cre)
Just delete any row from B where the key does not exist in A.
NOTE: "A" and "B" can't be aliases, they must be the actual table names.
Hope this helps!
Why not use id_cre from A table since both have the id.
This statement:
DELETE FROM B WHERE id IN (SELECT B.id from B LEFT JOIN A ON B.id_cred=A.id_cre WHERE a.id IS NULL)
simply says that both a and b (B.id_cred=A.id_cre) are the same.

Join 2 Tables When Table2 Doesn't Have Records Relating to Table1

I have two tables, call them Table1 and Table2. Table1 has a primary key of "ID" and Table2 has a foreign key field called "Table1ID".
I can run this join, but it will only work the way I want it to when there is a matching primary and foreign key value in both tables.
SELECT a.*, sum(b.Time) AS Time FROM Table1 AS a JOIN Table2 AS b ON a.ID = b.Table1ID
As you can see, I'm trying to pull all fields from Table1 and a sum of the field "Time" in Table2, where the primary and foreign keys match.
If there isn't a foreign key, I still want the record from Table1 to display, the "Time" field should simply show a 0.
First it sounds like you need to use aggregation since you're trying to sum the times for a given id. Use group by for that and define the fields as needed (vs *).
Second, you need to use an outer join to return those records that don't have matches.
Finally, you can use coalesce to convert null sums to 0:
SELECT a.id,
coalesce(sum(b.Time),0) AS Time
FROM Table1 AS a
LEFT JOIN Table2 AS b ON a.ID = b.Table1ID
GROUP BY a.id
SQL Fiddle Demo
Your query as written would not execute because you are not allowed to do an aggregate function in the select clause if other fields are present that are not in a group by clause. So a couple of options are:
Include every field in Table1 into your select and group by clauses such as:
SELECT a.ID, a.Attribute1, a.Attribute2, a.Attribute3...
, coalesce(sum(b.Time), 0) AS Time
FROM Table1 AS a
LEFT JOIN Table2 AS b
ON a.ID = b.Table1ID
Group by a.ID, a.Attribute1, a.Attribute2, a.Attribute3
Or you can create a sub-query that does the aggregation on on Table2 that is then joined with Table1.
SELECT a.*
, coalesce(b.Time, 0) AS Time
FROM Table1 AS a
LEFT JOIN
(
SELECT Table1ID, SUM(Time) Time
FROM Table2
GROUP BY Table1ID
) AS b
ON a.ID = b.Table1ID
Note that you need a LEFT JOIN, which means that every record in the first table (Table1) is returned whether or not there is a matching record in the second table. If you don't want a null in your results if there isn't a match, then you add the coalesce function to turn any nulls to zeros.