select data having same id - sql

id idtest result
1 1 2
1 2 1
1 3 2
2 1 2
2 2 1
2 3 1
3 1 1
3 2 2
3 3 1
Would like to get all the rows with the same IDs that matches the condition.
For example: get all the rows with the same id where (idTest=2 and result=1) and (idTest=3 and result=2)
result:
id idtest result
1 1 2
1 2 1
1 3 2
What would be the query???
Thanks!

Do you mean this?
SELECT * FROM table WHERE id = 1 and (result = 1 OR result = 2)
How about his:
SELECT *
FROM table WHERE (idTest = 2 OR idTest = 3) AND (result=1 OR result=2)

ID test res
1 1 2
1 2 1
1 3 2
2 1 1
2 2 2
2 3 2
3 1 1
3 2 2
3 3 1
Sorry. This would be my table. and Would like to get all the rows with the same IDs that matches the condition. For example: get all the rows with the same id where (test=2 and res=1) and (test=3 and res=2)
Result:
ID test res
1 1 2
1 2 1
1 3 2
What would be the query in order to get the three rows ?? Thanks!

You can use EXISTS:
SELECT id, idTest, result
FROM dbo.TableName t
WHERE EXISTS
(
SELECT 1 FROM dbo.TableName t2
WHERE t.id = t2.id
AND(
( t2.idTest=2 AND t2.result=1 )
OR
( t2.idTest=3 AND t2.result=2 )
)
)
Demo
Update: result is different:
id idTest result
1 1 2
1 2 1 <-- satisfies your condition
1 3 2 <-- satisfies your condition
2 1 2
2 2 1 <-- satisfies your condition
2 3 1
So either my understanding was incorrect or your expected result. I have also all ID=2 because the second id-2 row matches the condition.

You seem to want all rows for id's that have rows with that particular combination. What about:
with ids as (
select id
from mytable
where (idTest=2 and result=1) or (idTest=3 and result=2)
group by id
having count(id) = 2
)
select mytable.* from mytable
inner join ids
on ids.id = mytable.id
This gets a list of id's where both conditions apply, and then gets all rows for those id's.
SqlFiddle

SELECT *
FROM table t1
WHERE EXISTS (SELECT 1 FROM table WHERE id = t1.id AND idtest = 2 AND result = 1)
AND EXISTS (SELECT 1 FROM table WHERE id = t1.id AND idtest = 3 AND result = 2)
Just keep adding more AND EXISTS if you need more
Or you can use IN if it makes more sense to you
SELECT *
FROM table
WHERE id IN (SELECT id from table where idtest = 2 and result = 1)
AND id IN (SELECT id from table where idtest = 3 and result = 2)

do you need a method that treats the condition(s) in a generic way, like if they're values in another table? Or do you only need a way to pull results of two independent conditions?
If the latter, then this should work:
SELECT
id
FROM
(SELECT id
FROM tbl
WHERE idTest=2 AND RESULT=1) cond1 INNER JOIN
(SELECT id
FROM tbl
WHERE idTest=3 AND RESULT=2) cond2 ON
cond1.id = cond2.id
otherwise, if your conditions are generic and stored in a table, you'd need something like:
SELECT
id
FROM
(SELECT id
FROM tbl FULL OUTER JOIN conditions c
WHERE c.isUseMe = 1 AND c.SEQ = 1 AND idTest=c.idTestVal AND result=c.resultVal) cond1 INNER JOIN
(SELECT id
FROM tbl FULL OUTER JOIN conditions c
WHERE c.isUseMe = 1 AND c.SEQ = 2 AND idTest=c.idTestVal AND result=c.resultVal) cond2 ON
cond1.id = cond2.id
if the 4 values are passed in as parameters, you'd need something like:
SELECT
id
FROM
(SELECT id
FROM tbl
WHERE idTest=#idTestVal1 AND result=#resultVal1) cond1 INNER JOIN
(SELECT id
FROM tbl
WHERE idTest=#idTestVal2 AND result=#resultVal2) cond2 ON
cond1.id = cond2.id

Related

Insert into new table an id with several values

I've been struggling with this problem.
I have 2 populated tables and a third empty one and I would like to populate the third with data from the other two. Correlate values
The idea is to assign every single ID from the 1st table to entries (several) found in the 2nd table that respect the condition where DestinedUserTypeID should be equal to UserTypeID),
Table 1
Id
UserName
UserTypeID
1
Bla
1
2
Ble
2
3
Bli
3
Table 2
ID
TaskName
DestinedUserTypeID
1
Task A
1
2
Task B
1
3
Task C
1
4
Task D
2
DESIRED TABLE, Table 3
ID
UserID
TaskID
1
1
1
2
1
2
3
1
3
...
Insert into Table3 ([UserId],[TaskID])
SELECT
Id,
(SELECT [Id] FROM [Table2] t2
WHERE [Id] <= 5 AND [DestinedUserTypeId] = 1)
FROM t1 WHERE [UserTypeId] = 1
Thank you!
You can do it with a simple join linked to your table 1 and 2 and just insert into your table3
SELECT
u.id,
t.id,
from
table1 as u inner join
table2 as t on u.userTypeId = t.DestinedUserTypeID

Need help in creating SQL

I have table with following schema and contains records-
id parent_id active
1 NULL Y
2 1 Y
3 1 N
4 NULL Y
5 4 N
6 NULL N
7 6 N
I need to write a SQL for following use case:
Need to find all records whose active not equals to Y and whose parent_id active equals to Y.
Example output of above should be as follows:
output should be-
id parent_id active
3 1 N
5 4 N
You could do it using self join as below:
SELECT *
FROM mytab t1 INNER JOIN mytab t2
ON t1.id = t2.parent_id
WHERE t1.active != 'Y'
AND t2.active = 'Y'
You can do this using self-join as following:
select t1.id,t1.parent_id,t1.active
from test t1 inner join test t2 on t1.parent_id=t2.id
where t1.active <> 'Y' and t2.active='Y';
Results can be seen here:
DB Fiddle Demo
use subquery 1st take all the id's who have active=Y then check with parent_id and active column
select * from tbale_name where
parent_id in (
select id from table_name where active='Y'
) and active='N'
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=4a450a50a2ea6c3f4e1a19e2657ae35d
id parent_id active
3 1 N
5 4 N

Case for the whole dataset in sql table

Have a table like that. Let's pretend it is full table and we dont have any other rows:
ID Place
1 A
1 B
2 C
3 D
How can I perform such thing:
ID Place YesNo
1 A 1
1 B 1
1 C 0
1 D 0
2 A 0
2 B 0
2 C 1
2 D 0
3 A 0
3 B 0
3 C 0
3 D 1
For yes/no I need CASE statement but how to do the rest- full join table on itlself or some other options?
Thanks!
You can achieve that with two subqueries which each list the possible values of one of the columns. The two results should then be crossed to get all combinations. Finally outer join this with the original table to see which combinations actually occur:
SELECT first.ID,
second.Place,
CASE WHEN mytable.ID IS NULL THEN 0 ELSE 1 END AS YesNo
FROM (
SELECT DISTINCT ID
FROM mytable
) first
CROSS JOIN (
SELECT DISTINCT Place
FROM mytable
) second
LEFT JOIN mytable
ON mytable.ID = first.ID
AND mytable.Place = second.Place
ORDER BY first.ID,
second.Place
Here is an SQL fiddle

SQL Join with multiple row condition in second table

I have a question on SQL join which involve multiple condition in second joined table. Below is the table details
Table 1
pId status keyVal
---- ------- ------
100 1 45
101 1 46
Table 2
pId mode modeVal
100 2 5
100 3 6
101 2 7
101 3 8
I have above two tables and I am trying to join based on below condition to get pId's
pId's which has keyVal = 45 and status = 1 joined with table2 which has mode = 2 and modeVal 5 and mode =3 and modeVal = 6
the result I am expecting is to return pid = 100
Can you please help me with a join query ?
One way is to use GROUP BY with HAVING to count that the number of rows found is 2, of which 2 are matching the condition;
WITH cte AS (SELECT DISTINCT * FROM Table2)
SELECT t1."pId"
FROM Table1 t1 JOIN cte t2 ON t1."pId" = t2."pId"
WHERE t1."status" = 1 AND t1."keyVal" = 45
GROUP BY t1."pId"
HAVING SUM(
CASE WHEN t2."mode"=2 AND t2."modeVal"=5 OR t2."mode"=3 AND t2."modeVal"=6
THEN 1 END) = 2 AND COUNT(*)=2
If the values in t2 are already distinct, you can just remove the cte and select directly from Table2.
An SQLfiddle to test with.
SELECT columns
FROM table1 a, table2 B
WHERE a.pid = B.pid
AND a.keyval = 45
AND a.status = 1
AND (
(B.mode = 2 AND B.modeval = 5)
OR
(B.mode = 3 AND B.modeval = 6)
)
Below query should work for you perfectly
select distinct table1.pid FROM table1 JOIN table2
on table1.pid = table2.pid
WHERE table2.modeValue IN (5,6) AND table2.mode IN (2,3) AND table1.keyVal=45 and table1.status=1;

how to prevent duplicates with inner join query (Postgres)

I am trying to understand how to create a query to filter out some results based on an inner join.
Consider the following data:
formulation_batch
-----
id project_id name
1 1 F1.1
2 1 F1.2
3 1 F1.3
4 1 F1.all
formulation_batch_component
-----
id formulation_batch_id component_id
1 1 1
2 2 2
3 3 3
4 4 1
5 4 2
6 4 3
7 4 4
I would like to select all formulation_batch records with a project_id of 1, and has a formulation_batch_component with a component_id of 1 or 2. So I run the following query:
SELECT formulation_batch.*
FROM formulation_batch
INNER JOIN formulation_batch_component
ON formulation_batch.id = formulation_batch_component.formulation_batch_id
WHERE formulation_batch.project_id = 1
AND ((formulation_batch_component.component_id = 2
OR formulation_batch_component.component_id = 1 ))
However, this returns a duplicate entry:
1;"F1.1"
2;"F1.2"
4;"F1.all"
4;"F1.all"
Is there a way to modify this query so that I only get back the unique formulation_batch records which match the criteria?
EG:
1;"F1.1"
2;"F1.2"
4;"F1.all"
Thanks for your time!
In this case it is possible to apply the distinct before the join possibly making it more performant:
select fb.*
from
formulation_batch fb
inner join
(
select distinct formulationbatch_id
from formulation_batch_component
where component_id in (1, 2)
) fbc on fb.id = fbc.formulationbatch_id
where fb.project_id = 1
Notice how to use alias for the table names to make the query clearer. Also then in operator is very handy. The use of double quotes with those identifiers is not necessary.
One way would be to use distinct:
SELECT distinct "formulation_batch".*
FROM "formulation_batch"
INNER JOIN "formulation_batch_component"
ON "formulation_batch"."id" = "formulation_batch_component"."formulationBatch_id"
WHERE "formulation_batch"."project_id" = 1
AND (("formulation_batch_component"."component_id" = 2
OR "formulation_batch_component"."component_id" = 1 ))
I know the question asks how to prevent duplicates with inner join but could use an IN clause in the predicate.
SELECT "formulation_batch".*
FROM "formulation_batch" fb
ON "formulation_batch"."id" = "formulation_batch_component"."formulationBatch_id"
WHERE "formulation_batch"."project_id" = 1
AND fb.id IN (SELECT "formulation_batch"."id"
FROM formulation_batch_component
WHERE (("formulation_batch_component"."component_id" = 2
OR "formulation_batch_component"."component_id" = 1 ))