Is there a way to join two queries in SQL each with an order by? - sql

I have two queries that return data from two tables:
SELECT TOP 3
AE.id, AE.name, COUNT(R.id) 'number of reserves'
FROM
AIRPORT AE
INNER JOIN
FLY V ON V.id_destiny = AE.id
INNER JOIN
RESERVE R ON R.id_fly = V.id
GROUP BY
AE.id, AE.name
ORDER BY
COUNT(R.id) DESC;
Example of returned data:
id
name
number of reserves
6
name1
27
4
name2
18
14
name3
14
and
SELECT TOP 3
AE.id, AE.name, COUNT(R.id) 'number of reserves'
FROM
AEROPUERTO AE
LEFT JOIN
FLY V ON V.id_destiny = AE.id
LEFT JOIN
RESERVE R ON R.id_fly = V.id
GROUP BY
AE.id, AE.name
ORDER BY
COUNT(R.id) ASC;
Example of data returned from this second query:
id
name
number of reserves
7
name4
0
11
name5
0
12
name6
0
I need to combine these into a single output with the first query first (in the same order) and the second query next with the same order like this:
id
name
number of reserves
6
name1
27
4
name2
18
14
name3
14
7
name4
0
11
name5
0
12
name6
0
Is there a way to do it?
Edit: I have already tried the union all option, but I can't use the group by in each query so the table that is returned is different from what I need
(SELECT TOP 3 AE.id, AE.name, COUNT(R.id) 'number of reserves'
FROM AIRPORT AE
INNER JOIN FLY V
ON V.id_destiny = AE.id
INNER JOIN RESERVE R
ON R.id_fly = V.id
GROUP BY AE.id, AE.name)
UNION ALL
(SELECT TOP 3 AE.id, AE.name, COUNT(R.id) 'number of reserves'
FROM AEROPUERTO AE
LEFT JOIN FLY V
ON V.id_destiny= AE.id
LEFT JOIN RESERVE R
ON R.id_fly = V.id
GROUP BY AE.id, AE.name)
ORDER BY COUNT(R.id) ASC;

When you enclosed each query in parenthesis, it is acting like a derived table. You will need a SELECT clause to select from the derived table.
SELECT *
FROM
(
-- Your first query here
) AS Q1
UNION ALL
SELECT *
FROM
(
-- Your second query here
) AS Q2
You may also use CTE to do it
WITH
Q1 AS
(
-- Your first query here
),
Q2 AS
(
-- Your second query here
)
SELECT *
FROM Q1
UNION ALL
SELECT *
FROm Q2
EDIT : if you also wanted the final result in the same order in both query, add another column for final query ORDER BY
WITH
Q1 AS
(
SELECT TOP 3
AE.id, AE.name, COUNT(R.id) 'number of reserves',
Q = 1,
RN = ROW_NUMBER() OVER (ORDER BY COUNT(R.id) DESC)
FROM
AIRPORT AE
INNER JOIN
FLY V ON V.id_destiny = AE.id
INNER JOIN
RESERVE R ON R.id_fly = V.id
GROUP BY
AE.id, AE.name
ORDER BY
COUNT(R.id) DESC
),
Q2 AS
(
SELECT TOP 3
AE.id, AE.name, COUNT(R.id) 'number of reserves',
Q = 2,
RN = ROW_NUMBER() OVER (ORDER BY COUNT(R.id) DESC)
FROM
AEROPUERTO AE
LEFT JOIN
FLY V ON V.id_destiny = AE.id
LEFT JOIN
RESERVE R ON R.id_fly = V.id
GROUP BY
AE.id, AE.name
ORDER BY
COUNT(R.id) ASC
)
SELECT *
FROM Q1
UNION ALL
SELECT *
FROM Q2
ORDER BY Q, RN

I break the query and made two temp tables. You can do this in CTE (Commn Table expression) as well.
SELECT TOP 3 AE.id, AE.name, COUNT(R.id) 'number of reserves'
INTO #Temp_1
FROM AIRPORT AE
INNER JOIN FLY V
ON V.id_destiny = AE.id
INNER JOIN RESERVE R
ON R.id_fly = V.id
GROUP BY AE.id, AE.name
SELECT TOP 3 AE.id, AE.name, COUNT(R.id) 'number of reserves'
into #Temp_2
FROM AEROPUERTO AE
LEFT JOIN FLY V
ON V.id_destiny= AE.id
LEFT JOIN RESERVE R
ON R.id_fly = V.id
GROUP BY AE.id, AE.nam
SELECT *
FROM #Temp_1
UNION ALL
SELECT *
FROM #Temp_2
drop table #Temp_1
drop table #Temp_2

Related

SQL hierarchy - getting newest grandchild

I have a H2 database with a LEFT JOIN query on Bird which returns all birds along with the newest Health_Check.Catch_Date. I want to extend this query and include in the results newest PIT.ID, PIT.CODE and TRANSMITTER.IDc, TRANSMITTER.CHANNEL which are related to Health_Check.
Note: not every Health_Check has a relationship to a Transmitter or PIT.
A few notes about how the data is structured.
Most birds have several health checks;
Not every health check has a associated PIT or TRANSMITTER;
The newest Health_Check for a bird may not contain a PIT or TRANSMITTER;
Most birds have one PIT;
Most birds have a few Transmitters;
The date the Transmitter or PIT was attached is based on the related Health_Check.Catch_Date;
Most of my queries will require returning a Bird with the newest Health Check, PIT and Transmitter.
The SQL to get the newest HEALTH_CHECK is:
SELECT b.NAME, b.ID as birdId, hc1.CATCH_DATE, hc1.id as healthCheckId
FROM BIRD b
LEFT OUTER JOIN
( HEALTH_CHECK hc1
INNER JOIN
(
SELECT BIRD_ID, MAX(CATCH_DATE) AS MAX_DATE
FROM HEALTH_CHECK
GROUP BY BIRD_ID
) hc2
ON hc2.BIRD_ID = hc1.BIRD_ID AND
hc2.MAX_DATE = hc1.CATCH_DATE
)
ON hc1.BIRD_ID = b.ID;
Question: how can I also return in the results the most recent PIT and TRANSMITTER?
NB: The newest PIT and TRANS is often not on the newest HealthCheck. I am open to a schema change/adding a second relationship but I must be able to determine which HealthCheck a PIT and TRANS was attached in.
As an example results would look like:
BIRD.ID | BIRD.NAME | NEWEST HEALTH CHCECK | PIT.ID | PIT.CODE | TRANS.ID | TRANS.CHNL |
---------|-------------|----------------------|--------|----------|----------|------------|
1 | Bob | 2022-03-01 | AB001 | 3 | 2 | 40 |
2 | Jim | NULL | NULL | NULL | NULL | NULL |
3 | Jane | 2022-01-02 | DC123 | 2 | 3 | 50 |
One solution can be, to get the highest ID from every TRANs ANd PIT, i thinl that is the only ORDER that ic could find
Row_number would give every row for a specific chekc id, and the nimber 1 should be last one(ORDER BY ID DESC), it counts for every channel a new
SELECT b.NAME, b.ID as birdId, hc1.CATCH_DATE, hc1.id as healthCheckId
,PIT.ID , PIT.CODE,TRANS.ID , TRANS.CHANNEL
FROM BIRD b
LEFT OUTER JOIN
( HEALTH_CHECK hc1
INNER JOIN
(
SELECT BIRD_ID, MAX(CATCH_DATE) AS MAX_DATE
FROM HEALTH_CHECK
GROUP BY BIRD_ID
) hc2
ON hc2.BIRD_ID = hc1.BIRD_ID AND
hc2.MAX_DATE = hc1.CATCH_DATE
)
ON hc1.BIRD_ID = b.ID
LEFT JOIN
(SELECT ID, CODE,HEALTH_CHECK_ID
FROM
(SELECT ID , CODE,HEALTH_CHECK_ID
, ROW_NUMBER() OVER( PARTITION BY HEALTH_CHECK_ID ORDER BY ID DESC) rn FROM PIT) Pt
WHERE rn = 1) PIT ON PIT.HEALTH_CHeCK_ID = hc1.ID
LEFT JOIN
(SELECT ID, CHANNEL,HEALTH_CHECK_ID
FROM
(SELECT ID , CHANNEL,HEALTH_CHECK_ID
, ROW_NUMBER() OVER( PARTITION BY HEALTH_CHECK_ID ORDER BY ID DESC) rn FROM PIT) tr
WHERE rn = 1) TRANS ON TRANS.HEALTH_CHECK_ID = hc1.ID;
If there is a 1:1 relaionship you need only to join them,
SELECT b.NAME, b.ID as birdId, hc1.CATCH_DATE, hc1.id as healthCheckId
,PIT.ID , PIT.CODE,TRANS.ID , TRANS.CHANNEL
FROM BIRD b
LEFT OUTER JOIN
( HEALTH_CHECK hc1
INNER JOIN
(
SELECT BIRD_ID, MAX(CATCH_DATE) AS MAX_DATE
FROM HEALTH_CHECK
GROUP BY BIRD_ID
) hc2
ON hc2.BIRD_ID = hc1.BIRD_ID AND
hc2.MAX_DATE = hc1.CATCH_DATE
)
ON hc1.BIRD_ID = b.ID
LEFT JOIN
PIT ON PIT.HEALTH_CHeCK_ID = hc1.ID
LEFT JOIN
TRANS ON TRANS.HEALTH_CHECK_ID = hc1.ID;
if you need another heahc_ckes tarns and Pit that are not in the latest healthcheck, you need to add to the sunselect of the first query all healch ckes of that bird
SELECT b.NAME, b.ID as birdId, hc1.CATCH_DATE, hc1.id as healthCheckId
,PIT.ID , PIT.CODE,TRANS.ID , TRANS.CHANNEL
FROM BIRD b
LEFT OUTER JOIN
( HEALTH_CHECK hc1
INNER JOIN
(
SELECT BIRD_ID, MAX(CATCH_DATE) AS MAX_DATE
FROM HEALTH_CHECK
GROUP BY BIRD_ID
) hc2
ON hc2.BIRD_ID = hc1.BIRD_ID AND
hc2.MAX_DATE = hc1.CATCH_DATE
)
ON hc1.BIRD_ID = b.ID
LEFT JOIN
(SELECT ID, CODE,HEALTH_CHECK_ID,BIRD_ID
FROM
(SELECT ID , CODE,hc3.BIRD_ID,HEALTH_CHECK_ID
, ROW_NUMBER() OVER( PARTITION BY HEALTH_CHECK_ID ORDER BY hc3.CATCH_DATE DESC) rn FROM HEALTH_CHECK hc3 JOIN PIT ON hc3.ID = PIT.HEALTH_CHeCK_ID
WHERE hc3.BIRD_ID = hc1.BIRD_ID) Pt
WHERE rn = 1) PIT ON PIT.BIRD_ID = hc1.BIRD_ID
LEFT JOIN
(SELECT ID, CHANNEL,HEALTH_CHECK_ID,BIRD_ID
FROM
(SELECT ID , CHANNEL,HEALTH_CHECK_ID,BIRD_ID
, ROW_NUMBER() OVER( PARTITION BY HEALTH_CHECK_ID ORDER BY hc4.CATCH_DATE DESC) rn FROM HEALTH_CHECK hc4 JOIN PIT ON hc4.ID = PIT.HEALTH_CHeCK_ID
WHERE hc4.BIRD_ID = hc1.BIRD_ID) tr
WHERE rn = 1) TRANS ON TRANS.BIRD_ID = hc1.BIRD_ID;
For each bird (left join) to return a result set containing:
Newest health check (by date)
Recursively getting newest PIT (determined by date from related health check)
Recursively getting newest Trans (determined by date from related health check)
Noting that the PIT and Trans are often not on the newest Health Check can be done by:
SELECT *
FROM BIRD AS b
LEFT JOIN (
SELECT *
FROM (
SELECT id AS hc_id, bird_id, catch_date
, ROW_NUMBER() OVER (PARTITION BY bird_id ORDER BY catch_date DESC) AS n
FROM HEALTH_CHECK
) AS cte1a
WHERE n = 1
) AS cte1
ON cte1.bird_id = b.id
LEFT JOIN (
SELECT *
FROM (
SELECT p.id AS pit_id
, hc.bird_id
, p.Health_Check_Id
, p.code
, hc.catch_date as catchdate
, RANK() OVER (PARTITION BY hc.bird_id ORDER BY catch_date DESC) AS n
FROM PIT AS p
JOIN HEALTH_CHECK AS hc
ON p.Health_Check_Id = hc.id
) AS cte2a
WHERE n = 1
) AS cte2
ON cte2.bird_id = b.id
LEFT JOIN (
SELECT *
FROM (
SELECT t.id AS transmitter_id
, hc.bird_id
, t.Health_Check_Id
, t.channel
, hc.catch_date as catchdate
, RANK() OVER (PARTITION BY hc.bird_id ORDER BY catch_date DESC) AS n
FROM TRANSMITTER AS t
JOIN HEALTH_CHECK AS hc
ON t.Health_Check_Id = hc.id
) AS cte3a
WHERE n = 1
A fiddle is here.

Count Customers based on item master

I need you to help me on writing two queries in SQL Server 2008 that shows the following information based on item master:
Brand wise count on customer master plus customer who purchased the brand
Item Wise count of customer master plus customer who purchased the item
Here the link that shows the table information and the query which I tried.
Click here to view the table in SQL Fiddle
SELECT
brandname,
division,
route,
DivisionTotalCustomersCount = MAX(DivisionTotalCustomersCount),
RouteTotalCustomersCount = MAX(RouteTotalCustomersCount),
PurchasedCustomersCount = SUM(PurchasedCustomersCount)
FROM
(SELECT
i.brandname,
c.division,
c.route,
DivisionTotalCustomersCount =
(SELECT COUNT(distinct x.CustomerID)
FROM CustomerMaster x
WHERE x.division = c.division),
RouteTotalCustomersCount =
(SELECT COUNT(distinct x.CustomerID)
FROM CustomerMaster x
WHERE x.Route = c.route),
PurchasedCustomersCount = count(distinct C.CustomerID)
FROM CustomerMaster c
LEFT OUTER JOIN SalesData s on c.CustomerID = s.CustomerID
right outer join ItemMaster i on s.item = i.itemcode
GROUP BY i.brandname, c.division, c.route) A
GROUP BY
brandname, division, route
ORDER BY 1
Result Should as below
Excelsheet
I think you need to go reconsider the report and maybe splitting it out into multiple reports.
It does not make sense to have a route count as well as a divisional count if they are counting things at different levels of aggregation. So have a route count and division count report.
Either way, division and route is going to be null for 100PLUS because there are no customers for that brand which means there is no route or division info available.
--Division Count
SELECT BrandName, Division, COUNT(CustomerMaster.CustomerID) [Customer Count]
FROM ItemMaster LEFT OUTER JOIN
SalesData ON ItemMaster.BrandName = SalesData.Brand LEFT OUTER JOIN
CustomerMaster ON SalesData.CustomerID = CustomerMaster.CustomerID
GROUP BY BrandName, Division
--Route Count
SELECT BrandName, Route, Division, COUNT(CustomerMaster.CustomerID) [Customer Count]
FROM ItemMaster LEFT OUTER JOIN
SalesData ON ItemMaster.BrandName = SalesData.Brand LEFT OUTER JOIN
CustomerMaster ON SalesData.CustomerID = CustomerMaster.CustomerID
GROUP BY BrandName, Route, Division
Using your sqlfiddle data there are 25 sales records & 18 distinct brand/ division/ route/ customer records and there are no sales invloving 100PLUS
select
B.BrandName
, V.Division
, coalesce(Brand_count,0) as Brand_count
, coalesce(Division_count,0) as Division_count
from (select distinct BrandName from ItemMaster) as B
cross join (select distinct Division from CustomerMaster) as V
left join (
select
Brand
, Division
, sum(cust_count) over (partition by Brand) as Brand_count
, sum(cust_count) over (partition by Division) as Division_count
from (
select
S.Brand
, C.Division
, count(distinct S.CustomerID) cust_count
from salesdata as S
inner join CustomerMaster as C
on S.CustomerID = C.CustomerID
inner join ItemMaster as I
on S.item = I.ItemCode
group by
S.Brand
, C.Division
) as S
) as D
on B.BrandName = D.Brand
and V.Division = D.Division
order by
B.BrandName
, V.Division
;
| BRANDNAME | DIVISION | BRAND_COUNT | DIVISION_COUNT |
|-----------|----------|-------------|----------------|
| 100PLUS | Dubai | 0 | 0 |
| 100PLUS | RAK | 0 | 0 |
| KITCO | Dubai | 9 | 11 |
| KITCO | RAK | 9 | 7 |
| Red Bull | Dubai | 9 | 11 |
| Red Bull | RAK | 9 | 7 |
http://sqlfiddle.com/#!3/fecb0/27
All Credit to #kevriley
select
A.BrandName,
B.Division,
B.Route,
B.DivisionTotalCustomers,
B.RouteTotalCustomers,
isnull(C.PurchasedCustomersCount,0) as PurchasedCustomersCount
from
(
select distinct
BrandName, Route, Division
from dbo.ItemMaster
cross join dbo.CustomerMaster
) A
join
(
select distinct
Division,
Route,
DENSE_RANK() over (partition by Division order by c.CustomerID asc) + DENSE_RANK() over (partition by Division order by c.CustomerID desc) - 1 as DivisionTotalCustomers ,
DENSE_RANK() over (partition by ROUTE order by c.CustomerID asc) + DENSE_RANK() over (partition by ROUTE order by c.CustomerID desc) - 1 as RouteTotalCustomers
from CustomerMaster c
left join SalesData s on c.CustomerID = s.CustomerID
) B on B.Division = A.Division and B.Route = A.Route
left join
(
select
s.brand,
c.division,
c.route,
PurchasedCustomersCount = count(distinct C.CustomerID)
FROM CustomerMaster c
JOIN SalesData s on c.CustomerID = s.CustomerID
--join ItemMaster i on s.item = i.itemcode
GROUP by s.brand, c.division, c.route
) C on A.Brandname = C.Brand and C.Division = A.Division and C.Route = A.Route
See the same on SQL Fiddle
Select B.Brandname,B.Division,C AS DivisionTotalCustomerCount,
ISNULL(T.Count,0) AS PURCHASEDCUSTOMERSCOUNT
from
(
Select CM.Division,M.BrandName,COUNT(distinct CM.CustomerID) AS C
from dbo.CustomerMaster CM
CROSS JOIN ItemMaster M
GROUP BY CM.Division,M.BrandName
)B
LEFT JOIN
(Select Division,Brand,COUNT(Distinct C.CustomerID) As Count from CustomerMaster C
JOIN salesdata D
On C.CustomerID=D.CustomerID
where D.Brand='Red Bull'
GROUP BY Division,Brand
)T
ON B.Brandname=T.Brand
and B.Division=T.Division
Order by 1,2

Sql Query to find sum from different tables

Hi i require a help in writing a query.
Tables are:
tblStandard1students
tblStandard2students
tblStandard1students
tblDivision
tblCandidateinfo
tblStandard1students,tblStandard2students,tblStandard1studentstbl contain information about students enrolled in standard 1,2 and 3
tblStandars1students
Candid admitted
1 Y
2 N
3 Y
tblDivision contains only 2 columns
ID Division
1 A
2 B
3 C
tblCandidateinfo
Candid gender Division
1 M 1
2 F 2
and so on...
Now I want the table like this
Division Students(Standard1) Students(Standard2) Students(Standard3)
M F M F M F
------------------------------------------------------------------------
A 1 0 0 0 0 1
B 2 2 3 3 4 4
C 1 0 0 0 0 0
I tried this following query:
SELECT Division,
( SELECT count(*)
FROM tblStandard1students A
INNER JOIN tblCandidateinfo B ON A.Candid=B.Candid
INNER JOIN tblDivision C ON C.ID=B.Division) AS Students(Standard1),
( SELECT count(*)
FROM tblStandard2students A
INNER JOIN tblCandidateinfo B ON A.Candid=B.Candid
INNER JOIN tblDivision C ON C.ID=B.Division) AS Students(Standard2),
( SELECT count(*)
FROM tblStandard3students A
INNER JOIN tblCandidateinfo B ON A.Candid=B.Candid
INNER JOIN tblDivision C ON C.ID=B.Division ) AS Students(Standard3)
FROM tblDivision Z
but this is only half the query i din segregate it gender wise...help me to complete it.
;WITH combined AS
(
SELECT ci.Division, 'Students(Standard1) ' + ci.gender AS grp
FROM tblCandidateInfo ci
INNER JOIN tblStandard1students s ON ci.Candid = s.Candid
UNION ALL
SELECT ci.Division, 'Students(Standard2) ' + ci.gender AS grp
FROM tblCandidateInfo ci
INNER JOIN tblStandard2students s ON ci.Candid = s.Candid
UNION ALL
SELECT ci.Division, 'Students(Standard3) ' + ci.gender AS grp
FROM tblCandidateInfo ci
INNER JOIN tblStandard1studentstbl s ON ci.Candid = s.Candid
)
SELECT Division,
[Students(Standard1) M], [Students(Standard1) F],
[Students(Standard2) M], [Students(Standard2) F],
[Students(Standard3) M], [Students(Standard3) F]
FROM
(
SELECT d.Division, grp
FROM tblDivision d
LEFT OUTER JOIN combined c ON d.ID = c.Division
) x
PIVOT
(
COUNT(grp)
FOR grp IN ([Students(Standard1) M], [Students(Standard1) F],
[Students(Standard2) M], [Students(Standard2) F],
[Students(Standard3) M], [Students(Standard3) F])
) y
ORDER BY Division
SELECT divison.Division ,IFNULL(stander1.M,0),IFNULL(stander1.F,0) FROM test.tblDivision divison
Left join (SELECT division ,count( case gender when 'M' then 1 else null end) as M,count( case gender when 'F' then 1 else null end) as F
FROM
test.tblCandidateinfo tc inner join test.tblStandars1students ts1
ON tc.Candid=ts1.Candid
group by division) as stander1 on stander1.division= divison.id
group by divison.id
;
Insted of IFNULL use ISNULL and
take left join for all standar tables

Get Total Branch wise in SQL Server

SELECT b.BranchName ,
pm.AgreementValue
FROM dbo.Member AS m
INNER JOIN dbo.PlanMaster AS pm ON ( m.PlanId = pm.PlanId )
INNER JOIN dbo.Branch AS b ON ( b.BranchId = m.BranchId )
this is the result of above query
BranchName AgreementValue
------------------------------
abc 60000.00
abc 36000.00
abc 36000.00
xyz 20000.00
xyz 10000.00
now i want to get to total of AgreementValue BranchName wise..thanks for help
GROUP BY b.BranchName with SUM like so:
SELECT b.BranchName ,
SUM(pm.AgreementValue) TotalValue
FROM dbo.Member AS m
INNER JOIN dbo.PlanMaster AS pm ON ( m.PlanId = pm.PlanId )
INNER JOIN dbo.Branch AS b ON ( b.BranchId = m.BranchId )
GROUP BY b.BranchName;
If you are trying to get the total on each row, then use the window function for sum():
SELECT b.BranchName ,
pm.AgreementValue,
sum(pm.AgreementValue) over (partition by b.BranchName) as BranchTotal
FROM dbo.Member AS m
INNER JOIN dbo.PlanMaster AS pm ON ( m.PlanId = pm.PlanId )
INNER JOIN dbo.Branch AS b ON ( b.BranchId = m.BranchId )

Select Distinct Records for min date

I Have a query where In I need to select all the distinct ID's from the table, also need to select only the min(date) so that I get records that were inserted 1st and not ID's for all dates.
Basically this is what I am looking for -
Table 1 || Table 2-
ID || ID Date
1 || 1 11/11/2010
1 || 1 10/11/2010
3 || 3 12/01/2010
4 || 4 01/01/2010
4 || 4 02/01/2010
So i need to get all records from Table 2(table1.ID=table2.ID) which has the Minimum Date along with that ID
Result here would be
1 10/11/2010
3 12/01/2010
4 01/01/2010
Here is my query
select u.firstName,u.lastName ,count(*) as theCount
from tbl_appts_change_log c,tbl_appts a, tbl_users u
where c.appt_id=a.ID
and c.user_id=u.userID
and c.appt_id in ( select c.appt_id,min(c.date) from tbl_appts_change_log c, tbl_appts a
where c.appt_id=a.ID
and a.satellite_id='160' GROUP BY c.appt_id)
group by u.firstName,u.lastName
order by count(*) desc,u.firstName,u.lastName
maybe:
select u.firstName,u.lastName ,count(*) as theCount
from tbl_appts_change_log c
INNER JOIN tbl_appts a on c.appt_id=a.ID
INNER JOIN tbl_users u on c.user_id=u.userID
INNER JOIN ( select c.appt_id,min(c.date) as LastDate
from tbl_appts_change_log c
INNER JOIN tbl_appts a on c.appt_id=a.ID
Where a.satellite_id='160' GROUP BY c.appt_id) d
on c.appt_id = d.appt_id and c.date = d.LastDate
group by u.firstName,u.lastName
order by count(*) desc,u.firstName,u.lastName
I am ignoring your code as it seems to be a completely different scenario from what you have described in your question i.e Table1 and Table2. If all you want is the minimum date for each ID all you need is
SELECT T1.ID, MIN(T2.Date)
FROM Table1 T1
JOIN Table2 T2 ON T1.ID = T2.ID
GROUP BY T1.ID
But i am guessing what you really wanted was something like this?
Table 1 || Table 2-
ID || ID Date Desc
1 || 1 11/11/2010 AAA
1 || 1 10/11/2010 BBB
3 || 3 12/01/2010 CCC
4 || 4 01/01/2010 DDD
4 || 4 02/01/2010 EEE
And the expected result
1 10/11/2010 BBB
3 12/01/2010 CCC
4 01/01/2010 DDD
This is slightly more complicated than just doing a group by, and there are two ways to solve it. You could try both and see which one performs best
Method 1 : Using Row number
;WITH ResultCTE AS
(
SELECT T2.ID, T2.Date, T2.Desc,
RowNumber = ROW_NUMBER() OVER(PARTITION BY T2.ID ORDER BY T2.Date ASC)
FROM Table1 T1
JOIN Table2 T2 ON T1.ID = T2.ID
)
SELECT ID, Date, Desc
FROM ResultCTE
WHERE RowNumber = 1
Method 2: Nested query
;WITH ResultCTE AS
(
SELECT T2.ID, MIN(T2.Date) AS Date
FROM Table1 T1
JOIN Table2 T2 ON T1.ID = T2.ID
GROUP BY T2.ID
)
SELECT T.ID, T.Date, T.Desc
FROM Table2 T
JOIN ResultCTE R
ON R.ID = T.ID AND R.Date = T.Date
SELECT u.firstName,
u.lastName ,
COUNT(*) AS theCount
FROM tbl_appts_change_log c,
tbl_appts a,
tbl_users u
WHERE c.appt_id=a.ID
AND c.user_id =u.userID
AND a.satellite_id = '160'
AND c.date = (SELECT MIN(ci.date)
FROM tbl_appts_change_log ci,
tbl_appts ai
WHERE ci.appt_id = ai.ID
AND ci.appt_id = c.appt_id
AND ai.satellite_id= a.satellite_id
)
GROUP BY u.firstName,
u.lastName
ORDER BY COUNT(*) DESC,
u.firstName,
u.lastName
select u.firstName,u.lastName,count(*) as theCount,cm.MinDate
from (
select c.appt_id,min(c.date) as MinDate
from tbl_appts_change_log c, tbl_appts a
where c.appt_id=a.ID
and a.satellite_id='160'
GROUP BY c.appt_id
) cm
inner join tbl_appts_change_log c on cm.appt_id = c.appt_id and cm.MinDate = c.date
inner join tbl_appts a on c.appt_id=a.ID
inner join tbl_users u on c.user_id=u.userID
group by u.firstName,u.lastName
order by count(*) desc,u.firstName,u.lastName
If what you are looking for is-
Table 1 || Table 2-
ID || ID Date
1 || 1 11/11/2010
1 || 1 10/11/2010
3 || 3 12/01/2010
4 || 4 01/01/2010
4 || 4 02/01/2010
Try using this:
SELECT DISTINCT i1.id, i2.dt
FROM Table1 i1 JOIN (SELECT id, min(date) dt FROM Table2 GROUP BY id) i2
ON i1.id=i2.id
Is this what you're after?
select u.firstName,u.lastName ,count(*) as theCount
from tbl_appts_change_log c,tbl_appts a, tbl_users u
where c.appt_id=a.ID
and c.user_id=u.userID
and a.satellite_id = '160'
and c.date = (
select min(date)
from tbl_appts_change_log c, tbl_appts a
where c.appt_id = a.id
and a.satellite_id = '160'
)
group by u.firstName,u.lastName
order by count(*) desc,u.firstName,u.lastName