Can I use one query to count two columns in SQL - mysql

I have
office
office_id name
--------- -----------------
1 office1
2 office2
3 office3
person
uid office_id age gender
---------------------------
1 1 20 male
2 1 20 female
3 1 20 male
4 1 21 male
5 2 20 male
6 3 20 male
Is it possible I can use ONE query to get
office_id name age_20 male
-----------------------------
1 office1 3 3
2 office2 1 1
3 office3 1 1

Yes, you can. MySQL support boolean arithmethic and I think this is the shortest way to do it. If you want a more RDBMS friendly, use CASE WHEN age = 20 THEN 1 ELSE 0 END.
SELECT a.office_ID,
a.name,
SUM(age = 20) age_20,
SUM(gender = 'Male') male
FROM office a
LEFT JOIN person b
ON a.Office_ID = b.office_ID
GROUP BY a.office_ID, a.name
SQLFiddle Demo

Related

How to achieve below scenario with sql

The table structure
ID Name Cost
-------------------------
1 Peter 10
1 Peter 20
1 Peter 30
2 Lily 10
2 Lily 20
2 Lily 30
-------------------------
and I will like to achieve something as below for reporting
ID Name Cost
-------------------------
1 Peter 10
20
30
2 Lily 10
20
30
-------------------------
so what I have try is using left join but instead of giving me a results like above, it returns like this, exactly the same with the table structure.
ID Name Cost No Column Name
--------------------------------------
1 Peter 10
1 Peter 20
1 Peter 30
2 Lily 10
2 Lily 20
2 Lily 30
--------------------------------------
More of an expanded comment than an answer. Not properly tested or sure is the best method
select
case q.R when 1 then cast(q.id as nvarchar) else '' end as _id,
case q.r when 1 then q.nm else '' end as _nm,
q.cost
from
(
select
p.id,p.nm,p.cost,ROW_NUMBER() over (partition by p.id order by p.cost) as R
from tpeople as p
) as q
order by q.id

How to check for one value in multiple rows

Whats the best way to check if different groups of rows in a table with the same GroupID such as different teams have a SINGLE captain? Captain Identifier for example could be '10', so its crucial that it goes through multiple records with the same groupID and checks to see if theres ONLY ONE record with the positionID as '10'. I need it to do it for all teams, i.e all groupID's
-------------------------------------------------
ID | Group ID | Name | Position|
-------------------------------------------------
1 1 John 3
2 1 jim 3
3 1 Hahn 4
4 1 Mary 4
5 1 Moe 4
6 1 Charlie 10
7 2 taylor 4
8 2 Geoff 4
9 2 adam 4
10 2 cam 10
11 3 sharon 2
12 3 tony 4
13 3 steve 3
14 3 eve 4
15 3 gwen 10
--------------------------------
So what I need it to do is check that every groupID only had ONE 10 as the position.
Thanks in advance guys. Check out the image link at the bottom.
im using mysql btw
Sorry if this is badly described
If I understood you - I think you need something like :
select groupId, sum(case when positionID='10' then 1 else 0 end) as captains
from tbl_name
group by groupID
having captains = 1
am I close???
If I understood you correctly, you want an indication that will tell you whether the groupID had more then one captain.
So what you need is this:
select groupID,case when cnt = 1 then 1 else 0 end as IND_ONE_CAPTAIN from (
select groupID, sum(case when positionid = '10' then 1 else 0 end) as cnt
from players
group by groupID)
Now IND_ONE_CAPTAIN columns consist 1 or 0, 1 is for the group id only had 1 captain, and 0 is when they had more.

Add total of 3 rows for specific id

I have three tables:
Students
-------------------------------------------------------------
studentId first last gender weight
-------------------------------------------------------------
1 John Doe m 185
2 John Doe2 m 130
3 John Doe3 m 250
Lifts
-------------------
liftId name
-------------------
1 Bench Press
2 Power Clean
3 Parallel Squat
4 Deadlift
5 Shoulder Press
StudentLifts
------------------------------------------------
studentLiftId studentId liftId weight
------------------------------------------------
1 1 1 185
2 2 3 130
3 3 1 190
4 1 2 120
5 2 1 155
6 3 2 145
7 1 1 135
8 1 1 205
9 2 3 200
10 1 3 150
11 2 2 110
12 3 3 250
I would like to have four top lists:
Bench Press
Parallel Squat
Power Clean
Total of the above 3
I can successfully grab a top list for each specific lift using the following query:
SELECT s.studentId, s.first, s.last, s.gender, s.weight, l.name, sl.weight
FROM Students s
LEFT JOIN (
SELECT *
FROM StudentLifts
ORDER BY weight DESC
) sl ON sl.studentId = s.studentId
LEFT JOIN Lifts l ON l.liftId = sl.liftId
WHERE l.name = 'Bench Press'
AND s.gender = 'm'
AND s.weight > 170
GROUP BY s.studentId
ORDER BY sl.weight DESC
However, I am stuck on how to add the highest total of each lift for each student. How can I first find the highest total for each student in each lift, and then add them up to get a total of all three lifts?
Edit
The result set that I am looking for would be something like:
-------------------------------------------------
studentId first last weight
-------------------------------------------------
3 John Doe3 585
1 John Doe 475
2 John Doe2 465
I also forgot to mention that I would actually like two lists, one for students above 170 and one for students below 170.
SELECT -- join student a total weight to the student table
A.studentId,
A.first,
A.last,
C.totalWeight
FROM
Student A,
(
SELECT -- for each studet add the max weights
sum(B.maxWeight) as totalWeight,
B.studentID
FROM (
SELECT -- for each (student,lift) select the max weight
max(weight) as maxWeight,
studentId,
liftID
FROM
StudentLifts
GROUP BY
studentId,
liftID
) B
GROUP BY
studentId
) C
WHERE
A.studentID = C.studentId
-- AND A.weight >= 170
-- AND A.weight < 170
-- pick one here to generate on of the two lists.

Select min/max from multiple items

I'll try to explain it as simple as possible:
First some database structure with dummy data.
Structure
tb_spec_fk
feature value
-----------------
1 1
1 2
1 3
1 4
1 5
2 2
2 3
3 1
3 4
4 2
4 3
4 4
5 1
5 3
5 5
6 3
6 5
tb_spec_feature
feature_id filter
------------------
1 2
2 2
3 2
4 2
5 1
6 0
tb_spec_value
value_id name
----------------
1 10
2 20
3 30
4 40
5 50
Now, what I want is the follow result
Result
feature_id min_value max_value
---------------------------------
1 10 50
2 20 30
3 10 40
4 20 40
But how?
Logic
Get from the tb_spec_feature where "filter" equals 2 the highest and lowest values which are present in the tb_spec_value table and connected together trough the tb_spec_fk table.
My attemps
A lot! But I'll spare you :)
SELECT
f.feature_id AS feature_id,
MAX(value.name) AS max_value,
MIN(value.name) AS min_value
FROM tb_spec_feature AS f
JOIN tb_spec_fk AS fk ON f.feature_id=fk.feature
JOIN tb_spec_value AS value ON fk.value=value.id
WHERE f.filter=2
GROUP BY f.feature_id
The two JOIN statements "link" the a feature to a value. GROUP BY groups all rows with the same feature id, and then you can take the min or max or any other aggregate function on those columns.
Demo
Here is how you can do it
select
tsf.feature_id,
tsvl.name as Min_Value,
tsvr.name as Max_Value
from tb_spec_feature as tsf
inner join (select feature , MIN(value) MinV,MAX(value)MaxV from tb_spec_fk group by feature order by feature)as tsfkl on tsfkl.feature = tsf.feature_id
left join tb_spec_value as tsvl on tsvl.value_id = tsfkl.MinV
left join tb_spec_value as tsvr on tsvr.value_id = tsfkl.MaxV
where tsf.filter = 2
group by tsf.feature_id
Output
feature_id | Min_Value | Max_Value
---------------------------------
1 | 10 | 50
2 | 20 | 30
3 | 10 | 40
4 | 20 | 40
Fiddle Demo

complex sql query in sql server 2008

I have 4 major tables in my database.
Season --> seasonID
Trials --> trialID
Competition --> CID,name
Camps --> campID,DivisionID(FK)
Divisions ---> DivisionID
Contestants --->ContestantID
Now a contestant belongs to / are members of a divisions.
Then a division belongs to a camp.
All this leads to my Performance table.
PERFORMANCE TABLE
SeasonID|TrialID|CampID|DivID|CompetionID|CtestantID|Score1 |Score2 |Total
1 1 1 1 1 1 20 20 40
1 1 1 1 2 1 20 15 30
1 2 1 1 1 2 10 5 15
1 2 1 1 2 2 5 5 10
1 2 1 1 1 1 10 30 40
1 2 1 1 2 1 20 10 30
How can I query this performance table to give me the competition name, total score and rank (ranking over total score) of each contestant in each competition by trials and by seasons?
Example:
In season 1 and trial 2 I want to have:
SeasonID| TrialID | ContestantID| Competition | TotalScore | Rank
1 2 1 1 40 1
1 2 2 1 15 2
1 2 1 2 30 1
1 2 2 2 10 2
How do I go about this? I have tried table variables, pivot and joins but I can only rank by competitions, but I don't how to aggregate the results to get the result above!
I'm not exactly sure how you calculated your desired results. I think this is what you are after but, if so, the TotalScore in the desired results of your question should be 10 for the last record, not 20.
SELECT SeasonID, TrialID, ContestantID, CompetitionID, Total,
DENSE_RANK() OVER(PARTITION BY CompetitionId ORDER BY Total DESC) AS [Rank]
FROM PerformanceTable