I have a table "student" that features student's "name" and "DOB".
I would like to group students into the following groups:
a. 10-12
b. 13-14
c. 15-16
d. >= 17
so it would appear
a. paul, peter mary
b. john, william
etc.
How would I go about this?
So far I have:
select case
when age between 10 and 12 then a
when age between 13 and 14 then b
when age between 15 and 16 then c
when age >= 17 then d
from (
SELECT ROUND(DATEDIFF(Cast(CURRENT_TIMESTAMP() as Date),
Cast(birthday as Date)) / 365, 0) as age
FROM db.student
but can't seem to get my head around it.
I am using Management Studio.
Many thanks in advance.
The following query would probably get you the desired results. First, the age is determined. (I added the date format - day - in the DATEDIFF function). Then, the age category is determined.
WITH ages AS
(
SELECT
name,
ROUND(DATEDIFF(day, Cast(CURRENT_TIMESTAMP() as Date), Cast(birthday as Date)) / 365, 0) as age
FROM db.student
)
SELECT
name,
case
when age between 10 and 12 then a
when age between 13 and 14 then b
when age between 15 and 16 then c
when age >= 17 then d
end as age_category
FROM ages
ORDER BY name;
Related
I need your help with conditional "distinct on".
For example I have a table "users".
id
name
age
1
John
17
2
Sam
18
3
John
12
4
Sam
19
And I want to do something like:
select case when (u.age > 17) then (distinct on u.name u.*) else (u.*) from users u order by u.name
And I want to do "distinct on" BUT with exclusion, if age is less than 17, then display them as well, if age is greater then take random one.
The output I want is:
id
name
age
1
John
17
2
Sam
18
3
John
12
There are two users with name Sam, and both have age > 17, then I want to apply distinct on in this case.
But there's at least 1 John with age less than 17, therefore I want to have all users with name John in the output.
It might be possible to put this in a condition, but in my opinion, that leads to bad readability.
I would prefer to use UNION ALL here to clearly split these two parts of your query:
SELECT DISTINCT ON (name) id, name, age
FROM users
WHERE age > 17
UNION ALL
SELECT id, name, age
FROM users
WHERE age <= 17
ORDER BY id;
And yes, I know this will select twice from the table, but I think this better in this case unless you observe a very poor performance using this query.
I am currently writing some SQL for a project. I would like to try practicing case expressions, and in this case, practicing grouping records by age.
Here's the table I'm working with: Person
Name | Age
-----------
Mike | 32
Angela | 11
Chris | 65
Nat | 20
Sandra | 45
Shane | 82
I want to use a case expression to group these these people by age. I'd like to divide people into
-18 and younger
-19 to 40
-41 and older
So far, I've been trying to write a case expression like this:
select name, age
from person
order by
(case
when age < 18 //group first
when (age >= 19 and age < 40 //group second
else //group third
end);
Obviously this isn't working. I've been trying to understand case expressions a bit better, can anyone give me some pointers?
Here's what you are trying to achieve.
select name, age
from person order by
case when age < 18 then 0 when age >=19 and age <=40 then 1 else 2 end
We can try using a CASE expression to form the age groups:
SELECT
Name,
Age,
CASE WHEN Age <= 18 THEN 'young'
WHEN Age <= 40 THEN 'middle'
ELSE 'older' END AS age_group
FROM yourTable
ORDER BY
Age;
Try this.
Select AgeGroup, count(distinct *) as
count_names
from(SELECT NAME, CASE WHEN
Age <=
18 THEN 'young (1-18)'
WHEN Age <= 40 THEN 'Middle(19-
40)'
ELSE 'older (40-above)' END as
AgeGroup) group by AgeGroup
Suppose following table:
Name Age Occupation
Alex 20 Student
Alex 20 Seller
Alex 20 Minister
Liza 19 Student
Liza 20 Volunteer
Liza 21 HR partner
I want to find names which have only (and only) 20 in age column. So from this table I want to get all "Alex" rows and no "Liza" rows at all.
Thanks!
You need to use Group By and Having clause. Try this way
select Name
from table
group by Name
having count(case when Age = 20 then 1 end) = count(*)
count(case when Age = 20 then 1 end) counts only when age = 20 if it is equal to total count then the name has only 20 as age.
Just one another way:
select Name
from table
group by Name
having min(Age) = 20 and max(Age) = 20
One way is using NOT IN():
SELECT Name, Age, Occupation
FROM YourTable
WHERE Age = 20
AND Name NOT IN (SELECT Name FROM YourTable WHERE Age <> 20)
Here is the code:
SELECT * FROM COMPANY WHERE SALARY > 40000;
4 Mark 25 Rich-Mond 65000.0
5 David 27 Texas 85000.0
6 Kim 22 South-Hall 45000.0
8 Kitos 31 90000.0
SELECT * FROM COMPANY
WHERE AGE < (SELECT AGE FROM COMPANY WHERE SALARY > 40000);
3 Teddy 23 Norway 20000.0
6 Kim 22 South-Hall 45000.0
7 James 24 Houston 10000.0
How does this work when there are multiple row returned from the sub-query? In this example I would expect the last query to produce employees younger than 22 (minimum from the sub-query), apparently it doesn't work that way.
Most databases will raise an error if the subquery does not return exactly one result. SQLite doesn't, but just uses the first returned row (or NULL) (there is an implied LIMIT 1).
The order of SELECT results is not guaranteed without an ORDER BY, so the result will be random.
If you want to use some specific record, you must ensure that you SELECT returns exactly that record, typically using MIN/MAX, or with ORDER BY:
SELECT ...
FROM Company
WHERE Age < (SELECT MIN(Age)
FROM Company
WHERE Salary > 40000);
SELECT ...
FROM Company
WHERE Age < (SELECT Age
FROM Company
WHERE Salary > 40000
ORDER BY Age
LIMIT 1);
It is also possible to use a correlated subquery, which can return a different result for each row in the outer query:
SELECT ...
FROM Company
WHERE Age < (SELECT Age
FROM Company AS C2
WHERE C2.ID = Company.ManagerID);
In SQLite I am try to count people by current age when I have a column of birth dates
e.g
AGE: ------------------ COUNT:
17 ------------------------- 4
18 ------------------------- 7
19 ------------------------- 6
etc......
Many Thanks,
Z
Try this query:
select age,count(age) FROM
(select strftime('%Y',Date('now')) - strftime('%Y',birth) age
from table1)t
group by age;
SQL Fiddle