SQL from a column of a query to row of another query - sql

I am looking for a method that extracts the dates of Result 2, add
to be columns of Result 1, final as Expect result.
After Googled, I tried to use transform but mess result. How could
I build the result? Thanks.
Result 1:
merchantRef
totalAmount
country
1
10
UK
2
20
UK
3
60
UK
SELECT tblThree.merchantRef, tblThree.inDate
FROM tblThree;
Result 2 (tblThree):
merchantRef
inDate
1
12/21/2010
2
02/28/2021
3
06/15/2021
3
07/15/2021
Expect result:
merchantRef
totalAmount
country
inDate
inDate2
1
10
UK
12/21/2010
2
20
UK
02/28/2021
3
60
UK
06/15/2021
07/15/2021

You can use a lateral join -- which is like a subquery that can return multiple rows:
select t1.*, t3.*
from table1 t1 outer apply
(select nullif(min(t3.indate), max(t3.indate)) as indate1,
nullif(max(t3.indate), min(t3.indate)) as indate2
from table3 t3
where t3.merchantRef = t1.merchantRef
) t3;

Related

Selecting all rows from t1 join t2 on id and select the lowest value from t2 or null if not any

I have two tables, one holds some categories and the other holds players' records like so:
Categories Times
id Name id UserId MapId CategoryId Time
1 cat1 1 1 1 1 1500
2 cat2 2 3 1 2 3000
3 cat3 3 13 1 3 2500
4 cat4 4 12 1 4 1500
5 cat5 5 11 1 4 1000
I want to select all the categories (id, name) and the lowest time on each category.
If there's no record on that category it should show NULL or 0.
This would be the expected result:
Result
id Name Time
1 cat1 1500
2 cat2 3000
3 cat3 2500
4 cat4 1000
5 cat5 0
I'm using the following query, but it only selects the categories that already have a record in Times.
For example, if I use the following query it'll not select 'cat5' because it doesn't have any record in table Times.
select t2.id, t2.Name, min(t1.Time) as Time
from Times t1
join Categories t2 on t2.id = t1.CategoryId
where t1.MapId = %MAPID%
group by t2.id
I recommend to begin your query with the table "categories" in this case since your focus is on the data from this table. So you could write a left join. Furthermore, I think it's a good idea to replace null values by zero, thus your query would as example find negative times as the lowest times and return 0 if the lowest time is a null value.
Overall, this could be your goal:
SELECT c.id, c.name, MIN(COALESCE(t.time,0)) AS time
FROM categories c LEFT JOIN times t ON c.id = t.categoryid
GROUP BY c.id, c.name;
Here is a working example according to your sample data: db<>fiddle
There are likely also other options to achieve your goal, you can just try out.
I think you might just need to do a right join (because you want all rows from the 2nd table listed -- Categories). See if you get the desired results by changing line 3 to be:
right join Categories t2 on t2.id = t1.CategoryId

oracle sql to find the rows with one or more duplicate results in a same table

I have the below sample data set and I'm trying to come up with a query to find one or more duplicate rows from the same table
TABLE A: with 2 columns as below
CODE_NAME, RESULT
ABC 1
BBC 1
ZZZ 5
ZZZ 6
ZZZ 7
KBC 2
ZBC 2
CCC 2
XYZ 3
MNC 4
And my output should give all the unique rows with duplicate values in the result column such as below
CODE_NAME, RESULT
ABC 1
BBC 1
KBC 2
ZBC 2
CCC 2
i tried below but its not giving me correct result
select A t1, A t2
where A.result = b.result
and a.code_name <> b.code_name
Appreciate other suggestions.
You can use exists:
select t.*
from t
where exists (select 1
from t t2
where t2.result = t.result and t2.code_name <> t.code_name
);
For performance on a large dataset, you want an index on (result, code_name).
You might find it more convenient to have one row per duplicated result:
select result,
listagg(code_name, ',') within group (order by code_name)
from t
group by result
having count(*) > 1;

SQL count 2 equal columns and select other columns

I have a two separate tables, one with vacancies, and one with applications to those vacancies. I want to select a new table which selects from the vacancies table with a number of other columns from that table, and another column that calculates how many applications there are for those vacancies. So my vacancy table looks like this:
ID Active StartDate JobID JobTypeID HoursPerWeek
1 1 2017-02-28 2 CE 0
2 1 2017-02-15 4 CE 40
3 1 2017-02-14 1 CE 40
4 1 2017-02-28 1 CE 48
My applications table looks like this:
ID VacancyID Forename Surname EmailAddress TelephoneNumber
1 1 John Smith jsmith#gmail.com 447777777777
2 2 John Smith jsmith#gmail.com 447748772641
3 2 John Smith jsmith#gmail.com 447777777777
4 2 John Smith jsmith#gmail.com 447700123456
5 4 John Smith jsmith#gmail.com 447400123569
6 4 John Smith jsmith#gmail.com 447400126547
7 4 John Smith jsmith#gmail.com 447555123654
I want a table that looks like this:
ID Active StartDate JobID HoursPerWeek NumberOfApplicants
1 1 2017-02-28 2 0 1
2 1 2017-02-15 4 40 3
3 1 2017-02-14 1 40 0
4 1 2017-02-28 1 48 3
How can I select that table using joins and count the number of applicants where the VacancyID is equal to the ID of the first vacancy table? I have tried:
select Vacancy.ID, VacancyID, count(*) as NumberOfApplications from VacancyApplication
join Vacancy on Vacancy.ID=VacancyID
group by VacancyID, Vacancy.ID
This obviously doesn't select all the other columns and it also does not select ID 3 because there are 0 applications for that - I want ID 3 to be there with a value of 0 as well as all the other columns. How do I do this? I've tried various forms of grouping and selecting but I'm quite new to SQL so I'm not really sure how this can be done.
Use RIGHT JOIN instead of INNER JOIN and count the vacancyid column from vacancyapplication table. For the non matching records you will get count as 0
SELECT v.id, v.Active, v.StartDate, v.JobID, v.HoursPerWeek
Count(va.vacancyid) AS NumberOfApplications
FROM vacancyapplication va
RIGHT JOIN vacancy v
ON v.id = va.vacancyid
GROUP BY v.id, v.Active, v.StartDate, v.JobID, v.HoursPerWeek
Start using Alias names, it makes the query more readable
Hoping, i understood your problem correctly. Please try below query
select Vacancy.ID, VacancyID, count(*) as NumberOfApplications from VacancyApplication
left join Vacancy on Vacancy.ID=VacancyID
group by VacancyID, Vacancy.ID
You can use count as a window function using the OVER clause, thus eliminating he need for group by:
SELECT v.ID,
v.Active,
v.StartDate,
v.JobID,
v.JobTypeID,
COUNT(va.ID) OVER(PARTITION BY v.ID) HoursPerWeek
FROM Vacancy v
LEFT JOIN vacancyapplication va ON(v.ID = va.VacancyID)
Use left join and table aliases:
select v.ID, count(va.VacancyID) as NumberOfApplications
from Vacancy v join
VacancyApplication va
on v.ID = va.VacancyID
group by v.ID;
You seem to want all the columns. You could include them in the group by. However, a correlated subquery or outer apply is simpler:
select v.*, va.cnt
from vacancy v outer apply
(select count(*) as cnt
from VacancyApplication va
where v.ID = va.VacancyID
) va;
This is probably more efficient anyway, especially if you have an index on VacancyApplication(VacancyID).

Getting the most recent data from a dataset based on a date field

This seems easy, but I can't get it. Assume this dataset:
ID SID AddDate
1 123 1/1/2014
2 123 2/3/2015
3 123 1/4/2010
4 124
5 124
6 125 2/3/2012
7 126 2/2/2012
8 126 2/2/2011
9 126 2/2/2011
What I need is the most recent AddDate and the associated ID for each SID.
So, my dataset should return IDs 2, 5, 6 and 7
I tried doing a max(AddDate), but it won't give me the proper ID that's associated with it.
My SQL string:
SELECT First(Table1.ID) AS FirstOfID, Table1.SID, Max(Table1.AddDate) AS MaxOfAddDate
FROM Table1
GROUP BY Table1.SID;
You can use a subquery that returns the Maximum add date for each Sid, then you can join back this subquery to the dataset table:
SELECT
MAX(id)
FROM
ds INNER JOIN (
SELECT Sid, Max(AddDate) AS MaxAddDate
FROM ds
GROUP BY ds.Sid) mx
ON ds.Sid = mx.Sid AND (ds.AddDate=mx.MaxAddDate or MaxAddDate IS NULL)
GROUP BY
ds.Sid
the join still has to succeed if the MaxAddDate is NULL (there's no AddDate), and in case there are multiple ID that matches, it looks like you want the biggest one.
You can change your query to get the grouping first and then perform a JOIN like
SELECT First(Table1.ID) AS FirstOfID,
Table1.SID, xx.MaxOfAddDate
FROM Table1 JOIN (
SELECT ID, Max(AddDate) AS MaxOfAddDate
FROM Table1
GROUP BY SID) xx ON Table1.ID = xx.ID;
Try
select SID from table1
where addDate in (select max(addDate) from Table1)

How to Join two table using where and sum statement

Dear All I have below two table
Table1
RecdId RecdNo
1 A/1
2 A/2
3 A/3
Table2
RecdId RecdAmt1 RecdAmt2 RecdAmt3
1 100 10 5
1 150 20 10
1 200 30 15
2 500 5 50
2 400 10 60
3 100 5
I want solution that how to join above two table with sum of Table1.RecdId = Tabble2.RecdId
Below result I require
RecdId RecdNo TotRecdAmt1 TotRecdAmt2 TotRecdAmt3
1 A/1 450 60 30
2 A/2 900 15 110
3 A/3 100 5
Thanking You,
You can inner join two tables and use a group by clause to calculate sum for each combination of RecdId and RecdNo:
select t1.RecdId
, t1.RecdNo
, sum(t2.RecdAmt1) as TotRecdAmt1
, sum(t2.RecdAmt2) as TotRecdAmt2
, sum(t2.RecdAmt3) as TotRecdAmt3
from tbl1 t1
join tbl2 t2 on t1.RecdId = t2.RecdId
group by t1.RecdId
, t1.RecdNo
SQLFiddle
SELECT T1.RECDID, T1.RECDNO, TotRecdAmt1, TotRecdAmt2, TotRecdAmt3
FROM TABLE1 T1, (SELECT RECdID, SUM(RecdAmt1) TotRecdAmt1, SUM(RecdAmt2) TotRecdAmt2,
SUM(RecdAmt3) TotRecdAmt3 FROM TABLE2 GROUP BY RECdID) T2
WHERE T1.RECdID = T2.RECDID;
SELECT Table1.RecdId,RecdNo,SUM(RecdAmt1) AS TotRecdAmt1,
SUM(RecdAmt2) AS TotRecdAmt2,
SUM(RecdAmt3) AS TotRecdAmt3
FROM Table1,Table2
WHERE Table1.RecdId=Table2.RecdId
GROUP BY Table1.RecdId,RecdNo