Join column name to the value in another column - sql

I have the following tables:
Category Table
> ID Code CodeValue Value
> 1 sex 1 Male
> 1 sex 2 Female
> 2 age 1 Under 20
> 2 age 2 Between 20 and 40
> 2 age 3 Over 40
Data Table
> sex age
> 1 1
> 1 2
> 2 2
> 1 3
I want to return the Value of a field based on the Code, so that the final table would like something like below:
> sex age
> Male Under 20
> Male Between 20 and 40
> Female Between 20 and 40
> Male Over 40
Is there any way to join the values (sex age) of the 'Code' column in the Category Table with the column names in the Data table, and then return the corresponding 'Value' (Male, Female, Under 20 etc...)
Thanks!
Sam

You can join the table twice, once for each category.
SELECT cts.value sex, cta.value age
FROM data_table dt
INNER JOIN category_table cts
ON dt.sex = cts.code_value AND cts.code = 'sex'
INNER JOIN category_table cta
ON dt.age = cta.code_value AND cta.code = 'age'

Related

SQL Group by on multiple conditions on same table

enter image description hereI am trying to write an SQL query to get below output.
table has below data:
ID GENDER
10 M
10 F
10 F
20 F
20 M
Output:
ID Male Female
10 1 2
20 1 1
do i need to use case with group by. Can someone help here.
use simple group
select id,sum(case when GENDER = 'M' then 1 else 0 end) as Male,
sum(case when GENDER = 'F' then 1 else 0 end) as FeMale
from tablename
group by id

PostgreSQL: Finding students that have failed in more than 1 subject in their class (marks < 50)

I have a school table with 6 students each in class 1 and class 2, where each student has 5 subjects.
The table looks like this -
student_id Standard subject_id marks
1 1 1 30
2 1 1 45
3 1 1 45
4 1 1 55
5 1 1 80
6 1 1 20
1 1 2 40
2 1 2 75
3 1 2 25
4 1 2 40
Standard is the class of the student.
My question is I need to calculate the number of students that have failed in more than 1 subject in their class (marks < 50)
So far my failed attempt:
select count(*) from
(select student_id, marks < 50 as fail_value from school
group by 1,2
having count(subject_id) > 1
) as alias
where fail_value = 'true'
For reference, the expected result for the above table should look like this:
count_student_id
2
The derived table (the subquery) will return each student_id having more than one marks < 50 class. Count the number of rows returned.
select count(*)
from
(
select student_id
from school
where marks < 50
group by student_id
having count(subject_id) > 1
) as dt

getting count from multiple tables on the basis of gender and scored percentages

I have to use 3 tables
1. tbl_school_info
school_id school_name
1 St. Joseph
2 White Cross
2. tbl_student_info
student_id school_id student_name student_gender
1 1 maria liejal F
2 1 eerika carthy F
3 1 heron M
4 2 Glenn hui M
5 2 joseph M
6 2 christii F
7 2 hina moggy F
3. tbl_student_marks
marks_id school_id student_id scored_percentage
1 1 1 78
2 1 2 79
3 1 3 20
4 2 4 65
5 2 5 78
6 2 6 84
7 2 7 83
The result I need is the male, female and total student count in each school, male female passed student count and highest percentage scored male female students. The result will be like this ::
school_name || male_stud_cnt || female_stud_cnt || passed_male_cnt || passed_female_cnt || top_percentage_male ||top_percentage_female
St. Joseph 1 2 0 2 20 79
White Cross 2 2 2 2 78 84
The students whose score is below 35% has failed in the exam. How can I write query to get this result ? Is it possible to get such result using SQL query in MS SQL Server? I am unable to get the counts, how can I write such query ?
You can try using condtional aggregation with case when expression
with cte as
(
select school_name,a.student_id,student_gender,scored_percentage from
tbl_student_marks a inner join tbl_student_info b
on a.student_id=b.student_id
inner join tbl_school_info c on a.school_id=b.school_id
)
select school_name,
count(case when student_gender='M' then student_id end) as male_stud_cnt,
count(case when student_gender='F' then student_id end) as female_stud_cnt,
count(case when student_gender='M' and scored_percentage>35 then student_id end) as passed_male_cnt,
count(case when student_gender='F' and scored_percentage>35 then student_id end) as passed_female_cnt,
max(case when student_gender='M' then scored_percentage end) as top_percentage_male,
max(case when student_gender='F' then scored_percentage end) as top_percentage_female
from cte
group by school_name

Sort by aggregate value in sql

Let's say I have the following student data:
classroom gender student_id
-------------------------------------
First Grade M 123
First Grade F 124
First Grade F 125
Second Grade M 126
Third Grade M 127
...
I want to produce the following result: top 3 biggest classrooms ordered by total number of students with detail for each:
classroom boys_count girls_count total_count
--------------------------------------------------
Third Grade 30 30 60
First Grade 20 5 25
Fourth Grade 10 10 20
How can I do that in sql ? If necessary, I can use specific postrges features.
What I tried so far:
SELECT count(*) as total_count
, gender
, classroom
ORDER BY 1
GROUP BY classroom, gender
LIMIT 3
Then I re-organise results in some scripting language. But this is too slow. I want to have the correct results with one query
select classroom as name,
sum(case when gender = 'M' then 1 else 0 end) as boys_count,
sum(case when gender = 'F' then 1 else 0 end) as girls_count,
count(*) as total_count
from your_table
group by classroom
order by count(*) desc
limit 3

How to combine two tables to get results

The following is my master table:
tablename columnname size order
employee name 25 1
employee sex 25 2
employee contactNumber 50 3
employee salary 25 4
address street 25 5
address country 25 6
And following is my child table:
childid userid masterid isactive size order
1 1 1 Y 25 1
2 1 2 Y 25 2
3 1 3 N 0 0
4 1 4 Y 50 3
I would like to get the table name columnname from master table and size,order form child table against userid when isactive is Y in child table.
Some time, if the value is not there for the particular user than get all the values like tablename, columnname, size, order where isactive isY
I am really sorry to ask this but I am not good at SQL.
Regards.
Use INNER JOIN instead of LEFT JOIN
SELECT rcm.tablename, rcm.columnname, rcc.size, rcc.order
from report_customise_master rcm
INNER JOIN report_customise_child rcc
ON rcm.id = rcc.masterid
WHERE rcm.isactive = 'Y' and rcc.isactive = 'Y'
UPDATE 1
..., COALESCE(rcc.size, rcm.size) as Size,
COALESCE(rcc.`Order`, rcc.`order`) as `Order`