Using Group By on a non numeric field - sql

If I have a table like this:
ID | Name | Age
1 | Bill | 30
2 | Jim | 20
3 | Bill | 30
4 | Bill | 30
5 | Bob | 25
I want to return this:
ID | Name | Age
1 | Bill | 30
2 | Jim | 20
5 | Bob | 25
I tried this but it doesn't work:
SELECT ID,Max(Name),Age FROM TABLE
GROUP BY ID,Age
What do I got to do?

This should work:
select MIN(ID), NAME, AGE from TABLE group by NAME, AGE

Grouping by ID has no sense, because ID is already unique.
SELECT Max(Name), AGE
FROM TABLE
GROUP BY Age

Related

SQL SELECT most recently created row WHERE something is true

I am trying to SELECT the most recently created row, WHERE the ID field in the row is a certain number, so I don't want the most recently created row in the WHOLE table, but the most recently created one WHERE the ID field is a specific number.
My Table:
Table:
| name | value | num |SecondName| Date |
| James | HEX124 | 1 | Carl | 11022020 |
| Jack | JEU836 | 4 | Smith | 19042020 |
| Mandy | GER234 | 33 | Jones | 09042020 |
| Mandy | HER575 | 7 | Jones | 10052020 |
| Jack | JEU836 | 4 | Smith | 14022020 |
| Ryan | GER631 | 33 | Jacque | 12042020 |
| Sarah | HER575 | 7 | Barlow | 01022019 |
| Jack | JEU836 | 4 | Smith | 14042020 |
| Ryan | HUH233 | 33 | Jacque | 15042020 |
| Sarah | HER575 | 7 | Barlow | 02022019 |
My SQL:
SELECT name, value, num, SecondName, Date
FROM MyTable
INNER JOIN (SELECT NAME, MAX(DATE) AS MaxTime FROM MyTable GROUP BY NAME) grouped ON grouped.NAME = NAME
WHERE NUM = 33
AND grouped.MaxTime = Date
What I'm doing here, is selecting the table, and creating an INNER JOIN where I'm taking the MAX Date value (the biggest/newest value), and grouping by the Name, so this will return the newest created row, for each person (Name), WHERE the NUM field is equal to 33.
Results:
| Ryan | HUH233 | 33 | Jacque | 15042020 |
As you can see, it is returning one row, as there are 3 rows with the NUM value of 33, two of which are with the Name 'Ryan', so it is grouping by the Name, and returning the latest entry for Ryan (This works fine).
But, Mandy is missing, as you can see in my first table, she has two entries, one under the NUM value of 33, and the other with the NUM value of 7. Because the entry with the NUM value of 7 was created most recently, my query where I say 'grouped.MaxTime = Date' is taking that row, and it is not being displayed, as the NUM value is not 33.
What I want to do, is read every row WHERE the NUM field is 33, THEN select the Maximum Time inside of the rows with the value of 33.
I believe what it is doing, prioritising the Maximum Date value first, then filtering the selected fields with the NUM value of 33.
Desired Results:
| Ryan | HUH233 | 33 | Jacque | 15042020 |
| Mandy | GER234 | 33 | Jones | 09042020 |
Any help would be appreciated, thank you.
If I folow you correctly, you can filter with a subquery:
select t.*
from mytable t
where t.num = 33 and t.date = (
select max(t1.date) from mytable t1 where t1.name = t.name and t1.num = t.num
)
Look at your subquery. You want the maximum dates for num 33, but you are selecting the maximum dates independent from num.
I think you want:
select *
from mytable
where (name, date) in
(
select name, max(date)
from mytable
where num = 33
group by name
);

SQL Count of same country, same name, same age for people with same last name (e.g smith)

I need your advice.
we have the below table
Name of table: PEOPLE (i know bad name for example :-) )
ID | firstname | age | country
1 | George | 20 | US
1 | George | 20 | GB
2 | Jim | 20 | FR
2 | Jim | 21 | FR
i need to see the below result, so for same ID counts of values
ID | firstnamecnt | agecnt | countrycnt
1 | 2 | 2 | 1
2 | 2 | 1 | 2
I hope I explained well :-)
Thanks and regards,
Alex
I assume you meant firstname. Here is one way
select id,
count(*) - count(distinct firstname) + 1 as firstnamecnt,
count(*) - count(distinct age) + 1 as agecnt,
count(*) - count(distinct country) + 1 as countrycnt
from people
group by id;
DEMO

SQL select values sum by same ID

here is my table called "Employee"
eID | name |
==============
1 | Mike |
2 | Josh |
3 | Mike |
And table called "Sells"
sID | eID | | price |
=========================
1 | 1 | | 8 |
2 | 3 | | 9 |
3 | 3 | | 5 |
4 | 1 | | 4 |
5 | 1 | | 3 |
This should be my expected result: returns the total income per employee
name | Income |
==================
Mike | 15 |
Josh | 0 |
Mike | 14 |
Actually, I know use the query "SUM...GROUP BY..." to get the incomes of 15 and 14, but I don't know how to get the income of 0 which is not shown on the "Sells" table.
Could someone give me some help? Thanks a lot.
You just need to use a left outer join, so you can get the sum for missing values too. You could use case expression to deal with null values
SELECT e.name,
COALESCE(SUM(price), 0) as Income
FROM employees e
LEFT OUTER JOIN sells s
ON e.eid = s.eid
GROUP BY e.eid, e.name
Edited: case expression is not needed. I put coalesce on the return of sum fuction, in order to deal with missing values (SUM over an empty set returns NULL)

Group and sum on multiple ids

My brain has locked up on the following problem.
This for an Bi Publisher report
Users can select one or several employee names from a multi select dropdown
e.g John, Peter, Ann ...
In table Emp we have:
emp_id | emp_name
---
1 | John
2 | Peter
3 | Ann
Table worklimit
emp_id | limit | from_date | to_date
---
1 | 35 | 04-jul-2016 | 08-jul-2016
1 | 15 | 11-jul-2016 | 15-jul-2016
2 | 40 | 04-jul-2016 | 08-jul-2016
2 | 20 | 01-aug-2016 | 05-aug-2016
3 | 27 | 04-jul-2016 | 08-jul-2016
So the result I want is a total sum(limit) for the selected employee
e.g John + Ann 77
Or John + Ann + Peter = 137
This is just the first step. I need to sum up som values from a third table too, and I need to select a date range, and it must be grouped by week or month to make a barchart .
Can some of you clever brains out there point me in the right directions?
Try this:
SELECT SUM(A.limit) FROM
(
SELECT SUM(limit) limit,emp_name
FROM worklimit
JOIN Emp ON Emp.emp_id = worklimit.emp_id
GROUP BY emp_name
) A
WHERE emp_name IN ('John','Peter','Ann')

MS Access: Finding the top of each group in an SQL query

In my table, I have four columns.
I have a player name, an ID, an age, and a score.
ID | Player Name | Age | Score
------------------------------
0 | James | 24 | 20
1 | Carly | 24 | 25
2 | Matt | 24 | 19
3 | Jess | 26 | 35
4 | Jimmy | 26 | 32
5 | Tom | 27 | 19
6 | Brian | 27 | 25
I need to write a query to find the top player of each age group, but I am stumped. I've tried sorting both and using the Max() function, and I have tried manually looping through the values to find the top, but with no avail.
This is the sort of result I'd expect:
ID | Player Name | Age | Score
------------------------------
1 | Carly | 24 | 25
3 | Jess | 26 | 35
6 | Brian | 27 | 25
I am quite confused, and I'm sure there's a simple way to achieve this. Thanks.
One way to solve this is to create an inline view of the max scores per age and then join to it
SELECT p.*
FROM players p
INNER JOIN (SELECT age,
Max(score) as mScore
FROM players
GROUP BY age) AS mp
ON p.age = mp.age
AND p.score = mp.mscore
You should note that if there is tie for max more than one record can appear per age