How to complete this query function? - mysql

I have three tables.
Table A ###(Code, Value are combined primary key)
Code Value
1 | b
1 | c
3 | c
Table B
Value
b
Table C
Value
c
I would like to write a query of 'Code' from Table A.
The condition is that 'Code' should contain Value 'c'.
If 'Code' contains Value'b', this Code shouldn't be queried. (that's, Code 1 has value b and value c, so Code 1 needs to be excluded)
But I'm not available to do that query.
The expected outcome might be '3'
I want to use intersect but MySql doesn't contain this function yet.
So I tried some codes.
I'm sure that my codes have problems but I have no idea how to fix it.
SELECT DISTINCT A.*
FROM A B C
WHERE A.Value IN
(SELECT Value FROM B)
AND A.Value NOT IN
(SELECT Value FROM C);
Could you give me some tips on my questions?

the problem is that you are joining a, b and c. you almost got it.
select distinct a.value
from a
where a.value in (select value from b)
and a.value not in (select value from c)
or you can use join
select *
from a
inner join b where b.value = a.value
and not in (select value from c)

Related

SQL Query to compare two tables for names

I am building a SQL query which compares two tables A and B by a [name] column and returns the names from table A that are not in table B
Example
Table A
ID Name Address
1 A ABC
2 B XYZ
3 C PQR
Table B
ID Name Gender
1 A F
2 B M
3 D F
The query I wrote should return third row from table A as it is not in table B and should exclude all other rows
Following is the query I built
Select * from A oa left join B gp ON oa.name!=gp.name
the above doesn't return the results I was expecting.
Can this be corrected?
Easiest way:
select * from A where name not in (select name from B)
Better way:
select * from A where not exists (select 1 from B where B.name = A.name)
"A left join B" means keeping everything in A, and associating records in B if the condition is satisfied.
In your case, if you really wanna use left join, here is what it should be ('=', not '!='):
Select * from A oa left join B gp ON oa.name=gp.name where gp.name is null
Better way would be using 'not exists' performance-wise, or 'except' if null values are not an issue.
Using excpet operator will help
select * from TableA
except
select * from TableB
SELECT a.*
FROM A a
LEFT JOIN B b
ON a.name = b.name
WHERE b.name IS NULL

Subtract rows from a table, using subquery which may be empty

table: A
-----------
value
1
2
3
sub-query: B
-----------
value
2
I need (A - B).
The below query works when B is not empty. Output = (1,3) as expected.
SELECT * FROM A
JOIN B
ON (A.value != B.value)
However, when the sub-query B is empty, the JOIN does an intersection of A with an empty B, and the output is an empty result-set.
And if I use LEFT JOIN, it does not subtract the row containing value 2 from table A.
Is it possible to write a single query for (A - B), irrespective of whether B is empty or not.
SELECT A.*
FROM A
LEFT JOIN B
ON A.value = B.value
WHERE b.value IS NULL

MySQL: Combine multiple disparate tables into one

I have multiple tables, say A, B, and C where B and C have a foreign key to A.
I want to write a query that will return a result set where the columns of the result set are the columns of A and B and C combined, i.e.
A.id A.name B.id B.name C.id C.name
-----------------------------------
1 Thing 2 Bee NULL NULL
1 Thing NULL NULL 1 Cow
That is, essentially a combination of the results of an individual LEFT OUTER JOIN on B and C, but combined into a single result set. I am ok with there being multiple NULL columns.
EDIT: The result set will always have the entries of A, but only ONE of either B or C.
Is this possible? Or is there a better way of joining this information?
Since you never want a single row to contain both B and C, you might UNION together two separate join queries, substituting NULL literals for the opposite table to get the columns to align. Each part of the UNION supplies the relationship between A->B or A->C, but must return NULL for all the columns of the opposite table. Supply a NULL literal to leave empty every column from the other table.
In the end to sort them, you can conditionally check that the B columns are NOT NULL to force the B row to sort ahead of the C row, after first ordering by A.id.
(
SELECT
A.id AS a_id,
A.name AS a_name,
B.id AS b_id,
B.name AS b_name,
/* Substitute NULLs... for the other table C, for *all columns* */
NULL AS c_id,
NULL AS c_name,
NULL AS other_c
/* etc, other cols from C */
FROM A
LEFT JOIN B ON A.id = B.a_id
/* UNION, rather than UNION ALL in case both tables have NULLs */
) UNION (
SELECT
A.id AS a_id,
A.name AS a_name,
/* This time substitute NULLs for B, again *all columns* */
NULL AS b_id,
NULL AS b_name,
C.id AS c_id,
C.name AS c_name
C.other_c
FROM A
LEFT JOIN C ON A.id = C.a_id
)
ORDER BY
a_id,
/* sort the non-null B ahead... */
CASE WHEN b_id IS NOT NULL THEN 0 ELSE 1 END

MYSQL: Select column from table B if it exists, otherwise from table A

Table A
Name Value
John 1
Mary 2
Gary 3
Table B
Name Value
Jim 10
Jason 20
Mary 30
I want Name and Value from Table A, but overriding Value if exists in Table B. So my expected output would be:
John,1
Mary,30
Gary,3
I was trying something like:
SELECT A.Name, IF(EXISTS(B.Value),B.Value,A.Value) FROM Table A LEFT JOIN Table B on B.Name=A.Name
You can use the Mysql COALESCE function for this. It will return the first non-null argument in a list of parameters:
So your code would look something like:
SELECT A.Name,
coalesce(B.Value,A.Value)
FROM Table A LEFT JOIN Table B on B.Name=A.Name
So what would happens is that if there is a value in table B, that will be used, if not, it will revert to A.
See the docs: http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_coalesce
Try this instead:
SELECT
A.Name,
CASE WHEN b.Name IS NULL THEN a.Value ELSE b.value END AS value
FROM TableA AS a
LEFT JOIN TableB AS b on B.Name=A.Name;
SQL Fiddle Demo

mysql cross-updating a table

I can't figure out how to solve this problem.
I have a table (A) I need to update, with a structure like this:
CODE VALUE
1 a
2 null
3 null
etc...
Then I have another table (B) with the same structure but with every value set:
CODE VALUE
1 a
2 b
3 c
What I need to do is to copy data from table B to table A where A.CODE = B.CODE but only if A.VALUE is not set.
What's the best query to do so? Can't do it by hand since I'm dealing with 2000ish rows.
I wrote something like this but it doesn't seem to work:
update A set VALUE =
(select b.VALUEfrom B b, A a where b.CODE = a.CODE)
Thanks in advance!
UPDATE a SET a.Value = b.Value
FROM TableA a
INNER JOIN TableB b ON (a.CODE = b.CODE)
WHERE a.VALUE IS NULL
Check that a.VALUE is set to do the update, and only select from the B table in the inner clause (and use the value of A from the outer clause):
update A
set VALUE = (select B.VALUE from B where B.CODE = A.CODE)
where VALUE IS NULL;