Select all rows if only one matches - sql

I have two tables: FEATURE and FEATURE_DETAILS. Relation is one(FEATURE) to many(FEATURE_DETAILS).
feature_details_id | feature_id
1 1
1 2
1 4
2 1
2 2
2 4
2 5
3 1
3 5
How could I select all rows which contains e.g. 5?
feature_details_id | feature_id
2 1
2 2
2 4
2 5
3 1
3 5

first get the list of feature_deatails_id for which feature_id is 5, then pass the feature_deatails_id to FEATURE_DETAILS table to get the result
Try something like this
select *
from FEATURE_DETAILS
where feature_deatails_id in(
select feature_deatails_id from FEATURE_DETAILS where feature_id = 5)
or use Max()Over() Window function(preferred approach)
select * from
(
select max(case when feature_id = 5 then 1 else 0 end)over(partition by feature_deatails_id) as cnt,
feature_deatails_id,feature_id
from FEATURE_DETAILS
)s
Where cnt = 1

SELECT * FROM FEATURE_DETAILS WHERE feature_details_id IN (
SELECT feature_details_id from FEATURE_DETAILS WHERE feature_id=5
)

Related

Aggregate multiple rows between two numbers

Let's say we have this table:
table1
sensor_id
start_time_index
end_time_index
1
1
4
1
2
6
2
1
3
2
2
4
And another table with:
table2
sensor_id
time_index
value
1
1
'A'
1
2
'B'
1
3
'A'
1
4
'C'
1
5
'D'
1
6
'B'
2
1
'B'
2
2
'C'
2
3
'D'
2
4
'A'
Desired table is:
sensor_id
start_time_index
end_time_index
values_concatenated
1
1
4
"ABAC"
1
2
6
"BACDB"
2
1
3
"BCD"
2
2
4
"CDA"
I didn't know how to aggregate between a range that's specified between two values that are in two columns.
Using "range join" ON col BETWEEN ... AND ... and LISTAGG:
SELECT tab1.sensor_id, tab1.start_time_index, tab1.end_time_index,
LISTAGG(tab2.value) WITHIN GROUP(ORDER BY tab2.time_index) AS values_contatenated
FROM tab1
JOIN tab2
ON tab1.sensor_id = tab2.sensor_id
AND tab2.time_index BETWEEN tab1.start_time_index AND tab1.end_time_index
GROUP BY tab1.sensor_id, tab1.start_time_index, tab1.end_time_index

SQL: subset data: select id when time_id for id satisfy a condition from another column

I have a data (dt) in SQL like the following:
ID time_id act rd
11 1 1 1
11 2 4 1
11 3 7 0
12 1 8 1
12 2 2 0
12 3 4 1
12 4 3 1
12 5 4 1
13 1 4 1
13 2 1 0
15 1 3 1
16 1 8 0
16 2 8 0
16 3 8 0
16 4 8 0
16 5 8 0
and I want to take the subset of this data such that only ids (and their corresponding time_id, act, rd) that has time_id == 5 is retained. The desired output is the following
ID time_id act rd
12 1 8 1
12 2 2 0
12 3 4 1
12 4 3 1
12 5 4 1
16 1 8 0
16 2 8 0
16 3 8 0
16 4 8 0
16 5 8 0
I know I should use having clause somehow but have not been successful so far (returns me empty outputs). below is my attempt:
SELECT * FROM dt
GROUP BY ID
Having min(time_id) == 5;
This query:
select id from tablename where time_id = 5
returns all the ids that you want in the results.
Use it with the operator IN:
select *
from tablename
where id in (select id from tablename where time_id = 5)
You can use a correlated subquery with exists:
select t.*
from t
where exists (select 1 from t t2 where t2.id = t.id and t2.time_id = 5);
WITH temp AS
(
SELECT id FROM tab WHERE time_id = 5
)
SELECT * FROM tab t join temp tp on(t.id=tp.id);
check this query
select * from table t1 join (select distinct ID from table t where time_id = 5) t2 on t1.id =t2.id;

Select top year and term for each student

I want to return each student final semester record from these tables.
Table: dbo.Stdetail
StID YearID TermID
2 1 1
3 1 1
3 2 1
3 2 2
3 3 1
3 3 2
4 1 1
4 1 2
5 1 1
5 1 2
Table: dbo.lastyear
StID YearID TermID
1 5 1
2 5 1
2 6 2
3 5 1
3 6 2
From these two tables I want to return final yearID and term ID.
Desired output:
StID yearID TermID
1 5 1
2 6 2
3 6 2
4 1 2
5 1 2
I think you want to union together dbo.Stdetail and dbo.lastyear and then apply use row_number() to identify the most last record for each student. Like this:
;with cte as (select *
, row_number() over (partition by StID order by YearID desc, TermID desc) rn
from (select StID, YearID, TermID from dbo.Stdetail
union
select StID, YearID, TermID from dbo.lastyear) x
)
select *
from cte
where rn = 1

I need 2 count values from single column to be in same row using Over () clause

I have the following Result from Select statement
UnitId UnitType GroupId
1 1 1
2 1 1
3 1 2
4 2 2
5 2 2
6 2 2
7 2 2
I need the following result for each group Id
GroupId CountBasedOnUnitType1 CountBasedOnUnitType2
1 2 0
2 1 4
Thanks in advance.
Try this
SELECT * FROM
(
SELECT GroupId,
UnitType
FROM Table1
) x
Pivot
(
Count(UnitType)
For UnitType in ([1], [2])
) p
Fiddle Demo
Output
GroupId 1 2
1 2 0
2 1 4
Does in necessarily need to have OVER?
select
GroupID,
sum(case when UnitType = 1 then 1 else 0 end) CountBasedOnUnitType1,
sum(case when UnitType = 2 then 1 else 0 end) CountBasedOnUnitType2
from table
group by GroupID

MySQL - Selecting records based on maximum secondary ID

Here's part of my table:
id team_id log_id
1 12 1
2 12 1
3 12 1
4 12 1
5 1 2
6 1 2
7 1 3
8 1 3
What query would produce this output (so only the records with the highest log_id values are returned that correspond to team_id)?
id team_id log_id
1 12 1
2 12 1
3 12 1
4 12 1
7 1 3
8 1 3
SELECT *
FROM mytable t
WHERE log_id = (SELECT MAX(log_id) FROM mytable WHERE team_id = t.team_id)
SELECT id, team_id, log_id
FROM table1 t2
JOIN (SELECT team_id, MAX(log_id) max_log_id
FROM table1
GROUP BY team_id) t2 ON t1.team_id = t2.team_id
AND t1.log_id = t2.max_log_id