Select distinct rows based on column and two conditions in SQL - mysql

I would like to retrieve rows from this data set where a T1/T3 value exists, but no T2/T3 value exists for a corresponding ID.
ID sample1 sample2 value
A_000002 T2 T3 -0.934119
A_000002 T1 T3 -0.866637
A_000029 T2 T3 -1.07677
A_000037 T2 T3 -0.76506
A_000057 T1 T3 -5.34988
I'd like to say something like:
SELECT * FROM table
WHERE DISTINCT ID
AND sample_1 == "T1"
AND sample_2 == "T3"
...and return only the following because it has no corresponding T2/T3 row for that ID:
A_000057 T1 T3 -5.34988
If I use sample_1 and sample_2 conditions, I get distinct values anyway because it filters out the the "T2" values before checking if the ID is distinct.
The closest I've come is to make 3 tables with the possible T1/T2/T3 combinations and screen for NOT EXISTS T1T2.ID = T2T3.ID
select * from T1T2
where not exists (select * from T2T3 where T2T3.id = T1T2.id)
and not exists (select * from T1T3 where T1T3._id = T1T2.id)
order by id
I'm not sure I trust the code yet though.

You can use not exists :
select t.*
from table t
where (sample1 = 'T1' and sample2 = 'T3') and
not exists (select 1
from table t1
where t1.id = t.id and
t1.sample1 = 'T2' and t1.sample2 = 'T3'
);

You can use this technique based on an outer join:
select t1.*
from table t1
left join table t2
on t2.id = t1.id
and t2.sample1 = 'T2' and t2.sample2 = 'T3'
where t1.sample1 = 'T1' and t1.sample2 = 'T3'
and t2.id is null
It works because outer joins return nulls if there's no join, and you return only those via the t2.id is null condition in the where clause.
The big advantage of this technique is the efficient use of the index on the id column; this technique will generally out-perform other apporaches. Plus IMHO it's a neater looking query.
Note that the condition for the sample columns must be in the join condition for t2, otherwise you'd effectively get an inner join, defeating the required outer join.

I would use not exists:
SELECT t.*
FROM table t
WHERE t.sample_1 = 'T1' AND t.sample_2 = 'T3' AND
NOT EXISTS (SELECT 1 FROM table t2 WHERE t2.id = t.id);

Here will surly work:
Select distinct ID, * from table
Where sample1 = 't1' and sample2 = 't3'

Related

Return multiple rows from subquery

Basically I have two tables. 1 and 2. I need the field2 column in the table2 table to return multiple rows. I tried the below join (simplified the columns) but unfortunately it returns me only one result.
SELECT table1.field1, table1.field2, table1.field3, sub_q.field4
FROM table1
JOIN (
SELECT t2.field4, t2.filter1, t2.filter2 FROM table2 t2
) sub_q ON (sub_q.filter1 = table1.id AND sub_q.filter2 = 1)
##Should return multiple rows
##but returns only one!
WHERE table1.id = ..;
Edit:
I created a schema here: http://sqlfiddle.com/#!9/1c5737 with the select query as
SELECT t1.field1, t1.field2, t1.field3, t2.field1
FROM table1 t1
JOIN table2 t2 ON t2.filter1 = t1.id AND t2.filter2 = 1
WHERE t1.id = 1;
Only to find out that it works there, so I come back in shame to accept the answer and check where I messed up in my query (probably one of the fields)
Why are you using a subquery in the join? This is how it should be written:
SELECT table1.field1, table1.field2, table1.field3, t2.field1
FROM table1 t1
JOIN table2 t2 ON t2.filter1 = table1.id AND t2.filter2 = 1
Also it is likely that you need LEFT JOIN (or INNER JOIN) instead of JOIN, but cannot be sure without more details on what you're trying to achieve.

Using subquery in MySQL

I need some help with a specific problem about subqueries in MySQL. This is a shortversion of the problem I have:
I have table 1 and 2 where table 1 have a column called "SupplyID" which corresponds with table 2's "ID". I need to get a list with stuff from one single supplier.
I tried with this but didn't work:
select name
from item
where SupplyID exists (
select *
from SupplyID
where SupplyID = ID
);
Assuming your tables are named table1 and table2 you
You could use a inner join
select distinct t1.name
from ybale as t1
inner join table2 as t2 on t1.ID = t2.SupplyID
Try this:
select name from item i where exists (select * from table2 t where i.SupplyID = t.ID);
My answer is more like to what scaisEdge answered here but I strongly recommend to do this with LEFT JOIN. and If you want to select just one ID, for example ID=10
SELECT T1.name
FROM item AS T1
LEFT JOIN SupplyID AS T2 ON T2.SupplyID=T1.ID
WHERE T1.ID = 10

Conditional SELECT SQL with relational tables

Say I have an id in table1 which is a foreign key in table2 and there is a column in table2 called condition.
I need to select all ids from table 1 that aren't in table2 where condition = 1.
So for id in table 1 "select it" if it is not in table2 where condition = 1.
Edit: I used Ahsan Habib's answer and it worked great!
if you just want to select ID column from table1 this will work fine....Its just a simple set operation
select id from t1
minus
select id from t2 where condition = 1;
for all column you may try
select * from t1 whare id not in (select id from t2 where condition = 1);
This is almost a direct translation of what you are asking for:
select t1.*
from table1 t1
where t1.id not in (select t2.id from table2 t2 where t2.condition = 1);
Another way using NOT EXISTS
select t1.*
from table1 t1
where NOT EXISTS(select 1 from table2 t2 where t1.id = t2.id and t2.condition = 1);

How to perform subquery where subquery returns more than one row?

I'm trying to search for all entries in one table where they have a column that matches entries in another column that precede a -
Example Output:
This is the query I tried, it returned the error of "Error in query (1242): Subquery returns more than 1 row"
SELECT * FROM table1
WHERE
table1.Column1 = (
SELECT
SUBSTRING_INDEX(table2.Column1,'-',1)
FROM
table2
WHERE
table2.column1 LIKE '%\-%'
);
You can use IN in your WHERE clause :
SELECT * FROM table1
WHERE
table1.Column1 IN (
SELECT
SUBSTRING_INDEX(table2.Column1,'-',1)
FROM
table2
WHERE
table2.column1 LIKE '%\-%'
);
Another way is to use JOIN as
SELECT * FROM table1 t1
inner join (
SELECT
SUBSTRING_INDEX(table2.Column1,'-',1) as str
FROM
table2
WHERE
table2.column1 LIKE '%\-%'
)t2
on
t1.column1 = t2.str
;
DEMO

Merge two queries and return one of the possible values

select value1 as value from T1 where id=10;
if id does not exist in T1 - execute another query:
select value2 as value from T2 where id=10;
So, I want to join these queries and return a single value (value1 or value2). Is it possible?
SOLUTION:
My solution:
select ifnull(value1, value2) as value from T1 left join T2 using(id) where id=10;
you can join the query using union
select value1 as value from T1 where id=10
union
select value2 as value from T2 where id=10;
as a result you can get any one of the value or both
TRY (tested)
SELECT COALESCE(t1.value1, t2.value2) AS Value FROM t1
INNER JOIN t2 USING(id)
WHERE id=10
this will always check first the table t1 for id=10, if there is no value then see table t2 for the same id
Quoted FROM
The single result column that replaces two common columns is defined
using the coalesce operation. That is, for two t1.a and t2.a the
resulting single join column a is defined as a = COALESCE(t1.a, t2.a)
You can join the two queries on the id field and then use the COALESCE function to combine the two resulting fields into the output.
This assumes that you already have a list of IDs to join against, though. Otherwise you're stuck doing a union or full join to get such a list first.
You Can use this too
select Distinct(s1.id) from sample1 as s1 inner join sample2 as s2;
use union of both
like below :
select t1.id from table1 as t1 where id=10
union
select t2.id from table2 as t2 where id=10