joining two tables and avoid duplicate rows - sql-server-2014

I am stuck with below logic in sql server.
Table 1:
ID Requestid
1 0001
2 0004
3 0004
1 0005
Table 2
parentID Requestid Age
1 0001 29
2 0004 30
3 0004 34
1 0005 27
query:
select * from table1 t1
join table t2
on t2.parentid =t1.id
When I join these tables, I am getting below result
ID requestid age
1 0001 29
1 0005 29
2 0004 30
3 0004 34
1 0001 27
1 0005 27
I want below result:
ID requestid age
1 0001 29
1 0005 27
2 0004 30
3 0004 34
I know it is simple and i am missing something.
Any help is appreciated!

select ID, requestid, age from table1 t1
inner join table t2
on t2.parentid =t1.id AND t2.requestId = t1.requestId
ORDER BY ID
OR
select ID, requestid, age from table1 t1,table t2
where t2.parentid =t1.id AND t2.requestId = t1.requestId
ORDER BY ID

Related

Joining multiple tables with n to m relationships

I need to join three tables(from a MySQL database) where the second one is the link between the others.
The problem is tables 1 and 2 have multiple values (by Id or FeeId) and I cannot group in order to create a table like that:
EXPECTED RESULT TABLE
PaymentId
Amount
FeeCost
001
50
6
002
100
10
003
85
8
T1
PaymentId
Amount
0001
50
0002
75
0002
25
0003
20
0003
15
0003
50
T2
PaymentId
FeeId
001
AAA
002
AAB
003
AAC
T3
FeeId
FeeCost
AAA
2
AAB
4
AAC
3
AAC
2
AAC
3
AAA
2
AAB
4
AAA
2
AAB
2
I tried with multiple codes like that but I cannot join in a correct way
SELECT PaymentId, SUM(Amount), SUM(FeeCost)
FROM T2
INNER JOIN T1 ON T1.paymentId = T2.paymentId
INNER JOIN T3 ON T3.FeeId = T2.FeeId
GROUP BY T2.paymentId

How to select column and it's max

I have a mySQL table like:
ID Value
1 123
2 321
3 31
4 234
5 123
6 32
7 77
What I need to get is a table with additional column:
ID Value Maximum
1 123 321
2 321 321
3 31 321
4 234 321
5 123 321
6 32 321
7 77 321
But I have no idea how I should build a query.
Join your table with a subquery that gets the maximum.
SELECT t1.id, t1.value, t2.maximum
FROM yourTable AS t1
CROSS JOIN (SELECT MAX(value) AS maximum FROM yourTable) AS t2

Get count of items whilst selecting from the same table and then sorting by the count column

Say for example, I have a table that looks like this
ID NAME YREF UREF
1 ADAM BLAISE 0001 0007
2 JAMES HARDY 0002 0005
3 PHILIP HENRY 0003 0002
4 PETER SCHWARTZ 0004 0001
5 WILL MADISON 0005 0002
6 JEREMY PINOT 0006 0002
7 JOHN WILLIARD 0007 0007
8 MARK WILLIARD 0008 0005
9 JOHN VAUGHN 0009 0002
10 DAVID JAMES 0010 0002
I want to be able to get a count for each row how many times each user sent their YREF to another user so that the said user referenced it when submitting their own names, so that a table that looks like this can be got:
ID NAME YREF COUNT (i.e. how many times their YREF appeared in the UREF column of other users)
1 ADAM BLAISE 0001 1
2 JAMES HARDY 0002 5
3 PHILIP HENRY 0003 0
4 PETER SCHWARTZ 0004 0
5 WILL MADISON 0005 2
6 JEREMY PINOT 0006 0
7 JOHN WILLIARD 0007 2
8 MARK WILLIARD 0008 0
9 JOHN VAUGHN 0009 0
10 DAVID JAMES 0010 0
select t1.id, t1.name, t1.yref, coalesce(t2.cnt, 0) as count
from your_table t1
left join
(
select uref, count(*) as cnt
from your_table
group by uref
) t2 on t1.yref = t2.uref
Generate a set of data with counts and join it back to the base set. other database engines would allow windowed sets using OVER syntax, but mySQL doesn't support these.
SELECT A.ID, A.Name, A.YREF, coalesce(B.MyCount,0)
FROM tableName A
LEFT JOIN (SELECT count(*) myCount, UREF
FROM tableName
GROUP BY UREF) B
on A.YREF = B.UREF

list all students who have written atmost one exam per day

I have 3 tables likes Student,Subject,and Midterm tables.
Student table contains
studid Firstname lastname Class
1 A R 12A
2 B S 12A
3 C T 12A
4 D U 12A
5 E V 12B
SUBJECT table contains
subid subname
1 maths
2 science
3 english
MIDTERM table contains
studid subid marks examdate
1 1 100 2014-09-24
1 2 92 2014-09-25
1 2 92 2014-09-26
2 1 74 2014-09-24
2 2 78 2014-09-26
2 3 73 2014-09-26
3 1 90 2014-09-24
3 2 84 2014-09-25
3 2 92 2014-09-25
5 1 87 2014-09-24
4 2 79 2014-09-24
4 3 90 2014-09-26
select * from Student
EXCEPT
--list of students with more than one subject per day
select A.* from Student A
join
(select studid, examdate, count(distinct subid)cnt group by studid, examdate from [Midterm]
)B
on A.Studid = B.Studid
and B.cnt >1

select data based on multiple criteria (cloest value)

I am using MySQL. I'm trying to build something and just can't find a solution to a problem.
I am selecting a value from the lookup table based on my table as shown in the below example.
Select Criteria:
my.id<>l.id AND my.route1=l.route1 AND my.route2=l.route2 AND my.utc=l.utc
where my.stime is closest or same as l.stime
ex) my.id=2's col should get the l.id=1, l.etime=7777 since my.id<>l.id and the rest are the same.
ex) my,id=5's col has options l.id=3, l.etime=9999 and l.id=4, l.etime=7979 since my.id<>l.id, my.route=l.route, my.utc=l.utc. Yet, since my.stime=2220 is closer to l.stime=2222 than l.stime=3333 , l.id=3, l.etime=9999 will be chosen.
ex) my,id=6's col example is to select either value if "closest" is the same.
ex) my,id=7's col example is to return NULL when the criteria is not met.
Table: lookup (l.)
id route1 route2 utc stime etime
---|--------|--------|-----|-------|------
1 11 22 111 1111 7777
2 11 22 111 1111 8888
3 22 33 222 2222 9999
4 22 33 222 3333 7979
5 22 33 222 3335 8989
Table: my (my.) | result
id route1 route2 utc stime | l.id l.etime
---|--------|--------|-----|------- |-------|----------|
2 11 22 111 1111 | 1 7777
5 22 33 222 2220 | 3 9999
6 22 33 222 3334 | 4or5 7979or8989
7 22 33 999 9999 | null null
A new table should be created where the result is appended to the last col of my.
Any help is appreciated. Thanks in advance.
This solution is a bit convoluted, but it's a starting point.
First, let's create an auxiliary table:
CREATE TEMP TABLE temp AS
SELECT m.id mid, l.id lid, ABS(l.stime-m.stime) timediff
FROM my m JOIN lookup l
WHERE m.route1 = l.route1 AND m.route2 = l.route2 AND
m.utc = l.utc AND m.id <> l.id;
From this table we can get the minimum timediff for each my.id:
SELECT mid, min(timediff) mtimediff FROM temp GROUP BY mid
Result:
mid mtimediff
---------- ----------
2 0
5 2
6 1
Now we can find which rows in lookup have this stime difference, and choose the smallest id:
SELECT t.mid mid, min(lid) lid
FROM temp t JOIN (
SELECT mid, min(timediff) mtimediff FROM temp GROUP BY mid
) mt ON t.mid = mt.mid AND t.timediff = mt.mtimediff
GROUP BY t.mid
This is the result:
mid lid
---------- ----------
2 1
5 3
6 4
And finally we use those ids to extract the data from the tables:
SELECT m.id, m.route1, m.route2, m.utc, m.stime, l.id, l.etime
FROM my m JOIN lookup l JOIN (
SELECT t.mid mid, min(lid) lid
FROM temp t JOIN (
SELECT mid, min(timediff) mtimediff FROM temp GROUP BY mid
) mt ON t.mid = mt.mid AND t.timediff = mt.mtimediff
GROUP BY t.mid
) ON m.id = mid AND l.id = lid;
Giving:
id route1 route2 utc stime id etime
---------- ---------- ---------- ---------- ---------- ---------- ----------
2 11 22 111 1111 1 7777
5 22 33 222 2220 3 9999
6 22 33 222 3334 4 7979