In SQL, suppose that I have table A
ID
--
1
3
5
and table B
ID2
---
1
2
3
4
5
6
To get the result similar to:
ID | ID2
----------
1 | 1
1 | 2
3 | 3
3 | 4
5 | 5
5 | 6
For an explanation, an element in column ID2 will be mapped to the highest value in the column ID that is less than or equal to the said element in ID2.
For example, 4 in column ID2 is mapped to 3 from column ID, because 3 is the largest value in column ID which is less than or equal to 4.
Is it possible at all to do this in sql?
What I would do is start by joining the two tables on the condition that the id in the first table is less than or equal to that in the second table, like this:
SELECT t1.id, t2.id AS id2
FROM t1
JOIN t2 ON t2.id >= t1.id;
Once you have that, you can select the maximum id from the first table, and group by the id from the second table to get the largest pairs:
SELECT MAX(t1.id) AS id, t2.id AS id2
FROM t1
JOIN t2 ON t2.id >= t1.id
GROUP BY t2.id;
SQL Fiddle seems to be down but I will update with a link as soon as I can.
SELECT MAX(A.ID) ID, B.ID2
FROM A
INNER JOIN B ON B.ID2 >= A.ID
GROUP BY B.ID2
If you only need the matching ID column:
select b.*,
(select max(ID) from a where a.ID <= b.ID2) as a_Id
from b
If you need more columns:
select *
from a
join
(
select b.*,
(select max(ID) from a where a.ID <= b.ID2) as a_Id
from b
) as b
on a.Id = b.a_Id
Related
This question already has answers here:
Retrieving the last record in each group - MySQL
(33 answers)
Closed 11 months ago.
new to SQL but I'll try to be clear,
I have 3 table, which have corresponding key columns. I need to select the row the MAX Value of a set column, for EACH of it's corresponding column.
Table1
ID1 Value1
1 Marie
2 Max
3 John
Table2
ID2 Value2
1 First
2 Second
3 Third
Table3
ID1 ID2
1 1
1 2
2 1
2 2
2 3
3 1
So far I have something like so;
SELECT T1.Value1, T2.Value2 FROM Table1 T1
INNER JOIN Table3 T3 ON T1.ID1 = T3.ID1
INNER JOIN Table2 T2 ON T3.ID2 = T2.ID1
WHERE (That's where I can't formulate correctly)
So far my tables are correctly joined, but I want to output only the rows where ID2 is at it's max value for the corresponding ID1.
So we'd have
ID1 ID2
1 2
2 3
3 3
And so, from correspondence of value we'd finally have.
Value1 Value2
Marie Second
Max Third
John First
Any help? Also, group by is prohibited.
You must use MAX in WHERE condition:
SELECT
T1.Value1,
T2.Value2
FROM
Table1 T1
INNER JOIN Table3 T3 ON T1.ID1 = T3.ID1
INNER JOIN Table2 T2 ON T3.ID2 = T2.ID1
WHERE
T3.ID2 = (
SELECT
MAX(T3_alias.ID2)
FROM
Table3 AS T3_alias
WHERE
T3_alias.ID1 = T1.ID1
)
I have 3 tables:-
table1 :-
ReportType | ResourceId
t2 123
t3 5
table2:-
Id | Name | Created
1 A 10
2 B 11
123 C 12
table3:-
Id | Name | Created
4 D 13
5 E 14
6 F 15
table1's ResourceId and table2 and 3's Id column have same values
I want to create a 4th table like this:-
ReportType | ResourceId | Name | Created
t2 123 C 12
t3 5 E 14
such that wherever table1's ReportType is t2 I want the Name and Created value from table2 for the condition table1.ResourceId = table2.Id and wherever table1's ResourceType is t3 I want the Name and Created value from table3 for the condition table1.ResourceId = table3.Id.
PS: This isn't some sort of HomeWork. I have been stuck at this query for the past 1 hour, I have read various answers and tried a few queries of my own before posting the question. Any help would really be appreciated.
Explanation in comments :)
--here we join first and second table, but we filter results to include only ReportType = t2
select t1.ReportType, t1.ResourceId, t2.Name, t2.Created from table1 as t1 join table2 as t2 on t1.ResourceId = t2.id
where t1.ReportType = 't2'
union all
--here we join first and third table, but we filter results to include only ReportType = t3
select t1.ReportType, t1.ResourceId, t3.Name, t3.Created from table1 as t1 join table3 as t3 on t1.ResourceId = t3.id
where t1.ReportType = 't3'
You can use the below query:
select report_type, resourceid,name, created from dbo.t2, dbo.t1
where report_type='t2' and ResourceId=id
UNION
select report_type, resourceid,name, created from dbo.t3, dbo.t1
where report_type='t3' and ResourceId=id;
TABLE 1 TABLE 2
id name mob id course mark
1 joe 0000 1 English 77
2 john 0000 2 maths 89
I need to show the name of the person from table 1 who has the MAX(grade) in table 2 using a nested query.
SELECT t1.name
FROM t1
WHERE t1.id = t2.id = (
SELECT id
FROM t2
WHERE mark =
(
SELECT MAX(mark)
FROM t2
)
);
Well, this satisfies the brief ;-):
SELECT a.*
FROM table_a a
JOIN (SELECT * FROM table_b) b
ON b.id = a.id
ORDER
BY mark DESC
LIMIT 1;
I have a table as below
ID | CID
1 | 3
2 | 0
3 | 4
4 | 0
5 | 0
6 | 3
Below is the SQL query I use which is SELF JOIN.
SELECT t1.ID
FROM `tbl_a` AS t1 JOIN `tbl_a` AS t2
ON t1.ID = t2.CID
Which gives me O/P as below.
ID | CID
3 | 4
4 | 0
But what I want as an O/P is 1,3,4,6.
Logic of the O/P is Rows IDs or CIDs which are being used. If I explain more When the ID is 1 CID 3, When the ID is 3 CID is 4, When the ID is 6 CID is 3. When I get the unique IDs & CIDs that are used in the table would be 1,3,4,6.
Final Correct O/P Required is below.
ID
1
3
4
6
How can I get it done?
Not sure what you're trying to do. I think you are saying you want the ID of rows that have a non-zero CID or that are referenced by the CID column. (?) Try this:
SELECT ID FROM tbl_a AS t1 WHERE CID <> 0 OR EXISTS(SELECT * FROM tbl_a AS t2 WHERE t2.CID = t1.ID) ORDER BY ID
Try this
SELECT t2.ID
FROM `tbl_a` AS t1 JOIN `tbl_a` AS t2
ON t1.ID = t2.CID
OR t2.ID = t1.CID
GROUP BY t2.ID
I think this may be what you want:
select ID
from tbl_a
where id in (3, 4) or cid in (3, 4);
My SQL Skills are next to none. After looking around for the past 2 hours trying to figure this out I need some help please.
I have 2 tables as below
Table1 Table2
ID | Name Status_id
----------- ----------
1 | Open 1
2 | Closed 2
3 | On-Hold 1
What I would like to do is count the status_id in table 2 and group by the status_id. Then add the Name where the ID matches in the first column.
What I have at the moment is
SELECT status_id, COUNT(*) AS 'num' FROM table2 GROUP BY status_id
This is great so far and returns
1 | 2
2 | 1
What I need to return is
Open | 2
Closed | 1
I hope that is clear. Can anyone help?
Many thanks!
SELECT a.name, COUNT(*) AS num FROM table2 b
INNER JOIN table1 a
ON b.status_id=a.id
GROUP BY status_id
In the case that you want to also have Zero for On-Hold you'd need to do a LEFT join and count the a column from table2 instead of *
SELECT t1.name,
Count(t2.Status_id) AS num
FROM table1 t1
LEFT JOIN table2 t2
ON t1.id = t2.Status_id
GROUP BY t1.name;
DEMO