I have two tables (A and B) where my query compares a calculation from table A with a range in table B and then insert a corresponding value to the range(also in table B) in the third table(table C) based on dates. However,it is a possibility that table A may not have data for everyday and for those days i want to enter the value against the second lowest range.
TABLE B
id(PK)|date| v1 | v2
TABLE A
Aid|id(FK)|MinRange|MaxRange|Value
TABLE C
Cid|b.date|id(FK)|b.v1|b.v2|A.value
I am looking for a way to embed IF EXISTS in the WHERE clause something like this:
SELECT B.value
from TableB B
INNER JOIN TableA A ON A.id=B.id
WHERE B.id=4
and (IF DATA EXISTS) B.v1+B.v2 between A.min and A.max (ELSE Choose the second lowest A.min)`
The query above is an example to explain what i am trying to do, hence, it is not a valid query. I do not want to use a subquery for obvious performance issues.
I will appreciate any help.Thanks in advance :)
What about this
UPDATE
DECLARE myvar INT;
SELECT COUNT(*) INTO myvar FROM TableB WHERE Date=p_date;
SELECT myvar;
IF(myvar>0)
SELECT B.Date,A.Value
from TableB B
left JOIN TableA A ON A.id=B.id
WHERE B.id=4
ELSE
SELECT p_date AS Date,predefinedvalue AS Value
END IF;
You have to use left join because inner join will retrieve only the matching records. Also the predefined value has to be stored in B since if there is no matching record you can't query anything from A.
SELECT CASE WHEN myvar>0 THEN B.Date
ELSE p_date
END AS Date,
CASE WHEN myvar>0 THEN A.Value
ELSE predefinedvalue
END AS Value
from TableB B
left JOIN TableA A ON A.id=B.id
WHERE B.id=4
Related
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)
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
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.
I know this is a logic problem, however I am fairly new to SQL and do not know how to get through this one:
I have two tables.
Table A has a distinct ID.
Table B is used to store bits of data pertaining to any row in Table A.
Table B may have multiple rows which reference a single row of Table A.
How can i search for all of A's ID's in table B for which a single row of B does not equal a certain value?
SELECT DISTINCT table_a_id FROM table_b b WHERE b.meta_key != 'hidden'
since table_a_id is not distinct, this will return table_a_id's as long as the only row in table B for that particular table_a_id is not 'hidden'. Obviously it works if i am looking for each table_a_id which is hidden (if I use = instead of !=), but how do I accomplish the opposite?
Thanks
One method is to use group by with a having clause:
SELECT table_a_id
FROM table_b b
GROUP BY table_a_id
HAVING SUM(b.meta_key = 'hidden') = 0;
An alternative is to use not exists:
select a.id
from table_a a
where not exists (select 1
from table_b b
where a.id = b.table_a_id and b.meta_key = 'hidden'
);
This version actually has the advantage that it will show all rows from table_a, even when there are no rows in table_b. The first version will only show ids that have some data in table_b, just not the 'hidden' values.
I am having trouble with the relational algebra and transformation into SQL of this rather complicated query:
I need to select all values from table A joined to table B where there are no matching records in table B, or there are matching records but the set of matching records do not have a field that contains one of 4 of a possible 8 total values.
Database is MySQL 5.0... using an InnoDB engine for the tables.
Select
a.*
from
a
left join
b
on
a.id=b.id
where
b.id is null
or
b.field1 not in ("value1","value2","value3","value4");
I'm not sure if there is any real performance improvement but one other way is:
SELECT
*
FROM
tableA
WHERE
id NOT IN ( SELECT id FROM tableB WHERE field1 NOT IN ("value1", "value2"));
Your requirements are a bit unclear. My 1st interpretation is that you only want the A columns, and never more than 1 instance of a given A row.
select * from A where not exists (
select B.id
from B
where B.id=A.id
and B.field in ('badVal1','badVal2','badVal3','badVal4')
)
My 2nd interpretation is you want all columns from (A outer joined to B), with perhaps more than one instance of an A row if there are multiple B rows, as long as not exists B row with forbidden value.
select * from A
left outer join B on A.id=B.id
where not exists (
select C.id
from B as C
where A.id=C.id
and C.field in ('badVal1','badVal2','badVal3','badVal4')
)
Both queries could be expressed using NOT IN instead of correlated NOT EXISTS. Its hard to know which would be faster without knowing the data.