Grouping by a Concat Column problem SQL Server - sql-server

I am trying to group by the results of the query with a concat column, but I am stuck with it.
So this is my query:
SELECT
CONCAT (a.athleteLastName, ', ', a.athleteFirstName, ' (', a.athletePosition, ')') AS "Athlete",
COUNT(M.awardName) AS "Number of Awards Won"
FROM
award m
FULL OUTER JOIN
winner w ON m.awardId = w.awardId
FULL OUTER JOIN
athlete a ON w.athleteId = a.athleteId
GROUP BY
M.awardId, athleteLastName, a.athleteFirstName,a.athletePosition
ORDER BY
M.awardId DESC, Athlete;
This is the result:
Trout, Mike (OF) 1
Arenado, Nolan (3B) 4
Arenado, Nolan (3B) 7
Trout, Mike (OF) 3
But I want to group the count of awards by the player, and it should end like this:
Arenado, Nolan (3B) 13
Trout, Mike (OF) 4

How can Arenado, Nolan (3B) becomes 13? If simply summing up the awards, you can use subquery and can try this:
select "Athlete", sum("Number of Awards Won") as awards
from
(SELECT CONCAT (a.athleteLastName, ', ',a.athleteFirstName,' (',a.athletePosition,')') AS "Athlete" ,count(M.awardName) AS "Number of Awards Won" FROM award m
FULL OUTER JOIN winner w ON m.awardId = w.awardId
FULL OUTER JOIN athlete a ON w.athleteId = a.athleteId
GROUP BY M.awardId, athleteLastName, a.athleteFirstName,a.athletePosition
ORDER BY M.awardId DESC, Athlete ) as a group by 1;

Related

How to Left Inner Join two queries in Sybase?

I have two queries that should be joined together. Here is my query 1:
SELECT
t1.rec_id,
t1.category,
t1.name,
t1.code,
CASE
WHEN t1.name= 'A' THEN SUM(t1.amount)
WHEN t1.name = 'D' THEN SUM(t1.amount)
WHEN t1.name = 'H' THEN SUM(t1.amount)
WHEN t1.name = 'J' THEN SUM(t1.amount)
END AS Amount
FROM Table1 t1
GROUP BY t1.name, t1.rec_id, t1.category, t1.code
Query 1 produce this set of results:
Rec ID Category Name Code Amount
1 1 A MIX 70927.00
1 3 D MIX 19922.00
1 2 H MIX 55104.00
1 4 J MIX 76938.00
Then I have query 2:
SELECT
CASE
WHEN t2.category_id = 1 THEN SUM(t2.sum)
WHEN t2.category_id = 2 THEN SUM(t2.sum)
WHEN t2.category_id = 3 THEN SUM(t2.sum)
WHEN t2.category_id = 4 THEN SUM(t2.sum)
END AS TotalSum
FROM Table2 t2
INNER JOIN Table1 t1
ON t1.amnt_id = t2.amnt_id
AND t2.unique_id = #unique_id
GROUP BY t2.category_id
The result set of query 2 is this:
TotalSum
186013.00
47875.00
12136.00
974602.00
All I need is this result set that combines query 1 and query 2:
Rec ID Category Name Code Amount TotalSum
1 1 A MIX 70927.00 186013.00
1 3 D MIX 19922.00 47875.00
1 2 H MIX 55104.00 12136.00
1 4 J MIX 76938.00 974602.00
As you can see there is connection between table 1 and table 2. That connection is amnt_id. However, I tried doing LEFT INNER JOIN on query 1 and then simply using same logic with case statement to get the total sum for table 2. Unfortunately Sybase version that I use does not support Left Inner Join. I'm wondering if there is other way to join these two queries? Thank you
I wondered if the CASE statement makes sense in the first query because it sums in every row. Are there other values for the name column except A, D, H, J? If not you can change the CASE statement to SUM(t1.amount) AS Amount. Also the GROUP BY in the first query seems dubious to me: you are grouping by the record id column - that means you are not grouping at all but instead return every row. If that is what you really want you can omit the SUM at all and just return the pure amount column.
As far as I understood your problem and your data structure: the values in Table2 are kind of category sums and the values in Table1 are subsets. You would like to see the category sum for every category in Table1 next to the single amounts?
You would typically use a CTE (common table expression, "WITH clause") but ASE doesn't support CTEs, so we have to work with joins. I recreated your tables in my SQL Anywhere database and put together this example. In a nutshell: both queries are subqueries in an outer query and are left joined on the category id:
SELECT *
FROM
(
SELECT
t1.rec_id,
t1.category,
t1.name,
t1.code,
CASE
WHEN t1.name= 'A' THEN SUM(t1.amount)
WHEN t1.name = 'D' THEN SUM(t1.amount)
WHEN t1.name = 'H' THEN SUM(t1.amount)
WHEN t1.name = 'J' THEN SUM(t1.amount)
END AS Amount
FROM Table1 t1
GROUP BY t1.rec_id, t1.name, t1.category, t1.code
) AS t1
LEFT JOIN
(
SELECT category_id, SUM(sum) FROM
table2
GROUP BY category_id
) AS totals(category_id, total_sum)
ON totals.category_id = t1.category;
This query gives me:
Rec ID Category Name Code Amount Category_id total_sum
2 3 D MIX 19922.00 3 47875.00
3 2 H MIX 55104.00 2 12136.00
1 1 A MIX 70927.00 1 186013.00
4 4 J MIX 76938.00 4 974602.00
You surely have to tweak it a bit including your t2.unique_id column (that I don't understand from your queries) but this is a practical way to work around ASE's missing CTE feature.
BTW: it's either an INNER JOIN (only the corresponding records from both tables) or a LEFT (OUTER) JOIN (all from the left, only the corresponding records from the right table) but a LEFT INNER JOIN makes no sense.

Inner join with Count in SQL and group by

I have this table called Equipos.
id idType
1 1
3 2
4 3
5 4
6 4
And this other table which I want to Inner Join with (the catalogue with descriptions or ids).
id descripcion
1 Macbook
2 iMac
3 Dell Lap
4 Dell Lap OP
I want something like
descripcion count
Macbook 1
iMac 1
Dell Lap 1
Dell Lap OP 2
This is what Im trying so far.
select tipoId, count(tipoId)
from Equipos eq
group by tipoId
inner join TipoEquipo tip on tip.id=eq.idType
But to no avail.
This is indeed basic SQL, but I would prefer to use left outer join for this.
select tip.descripcion, count(eq.idType)
from TipoEquipo tip
left outer join Equipos eq on tip.id=eq.idType
group by tip.descripcion
This is basic sql, put join and group by in the right order and group by description not id.
select tip.descripcion, count(*) as count
from Equipos eq
inner join TipoEquipo tip on tip.id=eq.idType
group by tip.descripcion

Get distinct data from 2 tables using join

Below is my query . I take socail sercurity no from Employee table and match it with child_excel table. Using that I get Employee ID and matching that with EmployeeCh table (which has employee ID). The employee has 2 child's so when I put the gender clause I get 4 records 2 for each child with different (i.e Male, Female) for each of the child's. I want only 2 rows for child 1 for each child with their respective genders.
SELECT distinct
[SSN],
empch2.GenderID,
gen.Name1
FROM [child_excel] as t
INNER JOIN Employee as empch on t.SSN = empch.SocialSecurityNo
INNER JOIN EmployeeCh as empch2 on empch.ID = empch2.EmployeeID
INNER JOIN Gender as gen on empch2.GenderID = gen.ID
I am getting O/p as
12345 1 Male
12345 2 Female
99999 1 Male
99999 2 Female
Expected output is
12345 1 Male
99999 2 Female
But when I add First Name in the join it gives proper output. I dnt want to use first Name
SELECT distinct
[SSN],
empch2.GenderID,
gen.Name1
FROM [child_excel] as t
INNER JOIN Employee as empch on t.SSN = empch.SocialSecurityNo
INNER JOIN EmployeeCh as empch2 on empch.ID = empch2.EmployeeID and t.First_Name= empch2.FirstName
INNER JOIN Gender as gen on empch2.GenderID = gen.ID
Use ROW_NUMBER ()
Select * from (
SELECT distinct
[SSN],
empch2.GenderID,
gen.Name1,
ROW_NUMBER()OVER(PARTITION BY [SSN] ORDER BY empch2.GenderID)RN
FROM [child_excel] as t
INNER JOIN Employee as empch on t.SSN = empch.SocialSecurityNo
INNER JOIN EmployeeCh as empch2 on empch.ID = empch2.EmployeeID and t.First_Name= empch2.FirstName
INNER JOIN Gender as gen on empch2.GenderID = gen.ID )T
WHERE T.RN = 1

How to display only the MAX results from a query

I am new to writing MS SQL queries and I am trying to display only the record with the highest field named RecordVersion.
Below is the query that works but displays all records:
SELECT
PriceCalendars.PriceProgramID,
PriceCalendars.EffectiveDateTime,
PriceSchedules.Price,
PriceSchedules.PLU,
items.Descr,
PriceSchedules.LastUpdate,
PriceSchedules.LastUpdatedBy,
PriceSchedules.RecordVersion,
PriceSchedules.PriceScheduleUniqueID
FROM
PriceCalendars
INNER JOIN PriceSchedules ON PriceCalendars.PriceProgramID = PriceSchedules.PriceProgramID
INNER JOIN items ON PriceSchedules.PLU = items.PLU
WHERE
(PriceSchedules.PLU = 'SLS10100103')
AND (PriceCalendars.EffectiveDateTime = '2016-03-22')
Here are the query results:
PriceProgramID EffectiveDateTime Price PLU Descr LastUpdate LastUpdatedBy RecordVersion PriceScheduleUniqueID
1 2016-03-22 00:00:00.000 35.00 SLS10100103 Architecture Adult from NP POS 2015-01-22 07:53:15.000 GX70,83 9 569
1 2016-03-22 00:00:00.000 32.00 SLS10100103 Architecture Adult from NP POS 2014-02-25 16:22:46.000 GX70,83 5 86180
The first line of the results has RecordVersion being 9 and the second line results is 5, I only want the higher record displaying, the one that returned RecordVersion = 9.
Every time I try to use the MAX command I get errors or the group by and I have tried every example I could find on the web but nothing seems to work.
Using MS SQL 2012.
Thanks,
Ken
Try the following query which attempts to solve your problem by ordering the returned rows by RecordVersion DESC and then SELECTs just the first row.
SELECT TOP 1
PriceCalendars.PriceProgramID,
PriceCalendars.EffectiveDateTime,
PriceSchedules.Price,
PriceSchedules.PLU,
items.Descr,
PriceSchedules.LastUpdate,
PriceSchedules.LastUpdatedBy,
PriceSchedules.RecordVersion,
PriceSchedules.PriceScheduleUniqueID
FROM
PriceCalendars
INNER JOIN PriceSchedules ON PriceCalendars.PriceProgramID = PriceSchedules.PriceProgramID
INNER JOIN items ON PriceSchedules.PLU = items.PLU
WHERE
(PriceSchedules.PLU = 'SLS10100103')
AND (PriceCalendars.EffectiveDateTime = '2016-03-22')
ORDER BY
RecordVersion DESC
All group by columns should be in select ,that's the rule of group by.How group by works is for every distinct combination of group by columns,arrange remaining columns into groups,so that any aggregation can be applied,in your case I am not sure what group by columns are unique with out test date.here is one version which use row number which gives you the output desired
Remember ,order by last updated date is the one which decides rows order and assign numbers
WITH CTE
AS
(
SELECT PriceCalendars.PriceProgramID,
PriceCalendars.EffectiveDateTime,
PriceSchedules.Price,
PriceSchedules.PLU,
items.Descr,
PriceSchedules.LastUpdate,
PriceSchedules.LastUpdatedBy,
PriceSchedules.RecordVersion,
PriceSchedules.PriceScheduleUniqueID,
ROW_NUMBER() OVER (PARTITION BY PriceSchedules.RecordVersion ORDER BY PriceSchedules.LastUpdatedBy) AS RN
FROM
PriceCalendars
INNER JOIN PriceSchedules ON PriceCalendars.PriceProgramID = PriceSchedules.PriceProgramID
INNER JOIN items ON PriceSchedules.PLU = items.PLU
WHERE
(PriceSchedules.PLU = 'SLS10100103')
AND (PriceCalendars.EffectiveDateTime = '2016-03-22')
)
SELECT * FROM CTE WHERE RN=1

how to group in two tables in SQl server?

I have the following issue :
table # 1 structure :
Requests table for example have 2 columns :
Request_ID Branch_Name
1 xx
2 yy
3 xx
4 xx
5 yy
The second table : Requests_Items for example have the following columns
Request_ID Price
1 100
1 30
1 450
2 10
2 18
So i want my result set to be like :
Branch Name Num_of_Requests Total_Price
xx 3 580
Can you please help
select r.Branch_Name,
count(r.request_id) as Num_of_Requests,
sum(i.price) as Total_Price
from Requests r
left join Requests_Items i on i.Request_ID = r.Request_ID
group by r.Branch_Name
jurgen d was almost there
select r.Request_Id, r.Branch_Name,
COUNT(i.Price) as [Number of Requests],
SUM(i.Price) as [Total]
from Requests r
left join Requests_Items i
on r.Request_Id = i.Request_Id
group by r.Request_Id, r.Branch_Name
select r.Branch_Name, COUNT(ri.Request_ID) as Num_of_Requests, SUM(ri.Price) as Total_Price
from dbo.Requests r
left join dbo.Requests_Items ri
on r.Request_ID = ri.Request_ID
group by r.Branch_Name
Let this is my [Employees] Table
Here is my Dept table
I want the output like this using join and group by
So here is the Query for this-
select max(e.salary) as maxsalary,d.Dept from Employees e inner join DEpt d on e.DeptId=d.id group by e.DeptId,d.Dept
enter code here

Resources