I have 2 tables like that:
Student
ID | Name | Age
1 | Jonh | 20
2 | Smit | 19
3 | David | 28
4 | Simon | 18
5 | Kate | 17
6 | Marry | 20
Rating
Studen_ID | mark
1 | 10
1 | 5
2 | 7
3 | 9
3 | 8
I want to Select "Student" with Ratting" and show "Reporting" like that:
Reporting
ID | Name | Age | avg_mark
1 | Jonh | 20 | 15
2 | Smit | 19 | 7
3 | David | 28 | 17
4 | Simon | 18 | null
5 | Kate | 17 | null
6 | Marry | 20 | null
Please help me to do that. I am so stupid ><
Thanks
Nguyen
This query gets the students that have ratings, showing their name and average mark. If you want to show all of them regardless if the have or not rating, change the INNER by LEFT.
SELECT s.id, s.name, s.age, AVG(r.mark) AS avg_mark
FROM student s
INNER JOIN rating r ON s.id = r.student_id
GROUP BY s.id, s.name, s.age
Try this:
select id, name, age, sum(mark) as avg_mark from student
left join rating on student.id = rating.student_id
group by student.id, student.name, student.age
But note that in your example the avg_mark is actually the sum, not the average. If you want average (rounded) you should use avg(mark) instead like this:
select id, name, age, avg(mark) as avg_mark from student
left join rating on student.id = rating.student_id
group by student.id, student.name, student.age
Sample SQL Fiddle for both queries.
Related
I have table sellers where I list every single one of my sellers, and I added the column objective recently.
id |name | team_leader_id | team_leader | objective
--------------------------------------------------
1 |John | 50 | Mark | 30
2 |Jane | 66 | Ryu | 30
3 |Angela | 66 | Ryu | 45
4 |Arthur | 190 | Carol | 35
5 |Anthony| 20 | Adam | 50
I have another table sales where I link my sellers table on seller_id.
sale_id |seller_id |seller_name |item
-------------------------------------
56879 |2 |Jane |4P
23512 |2 |Jane |3P
54827 |2 |Jane |3P
12345 |5 |Anthony |4P
55435 |4 |Arthur |GSM
The query I'm trying is:
SELECT coalesce(seller.team_leader,'') team_leader,
coalesce(sales.seller_name,'TOTAL') seller_name,
seller.objective,
count(*) as quantity
FROM sales
JOIN seller ON seller.id = sales.seller_id
WHERE seller.team_leader_id = 66
GROUP BY seller.team_leader, ROLLUP(sales.seller_name), seller.objective
I noticed that the result I'm getting a duplicate of every line that now has an objective.
I think the problem is because my objective column is new, and I'm joining my sales table with my seller table, it counts the records I had before creating the objective column separately.
So, my expected result would be
team_leader | seller_name | objective | quantity
------------------------------------------------
Ryu | TOTAL | | 3
| Jane | 30 | 3
| Angela | 45 | 0
But this is what I'm getting
team_leader | seller_name | objective | quantity
------------------------------------------------
Ryu | TOTAL | | 1
Ryu | TOTAL | 30 | 2
| Jane | | 1
| Jane | 30 | 2
| Angela | 45 | 0
When the objective appears blank with Jane, it is a sale that she did before I added the objective column.
You can try the following :
SELECT case when seller.name is null then max(seller.team_leader) else '' end as team_leader,
isnull(seller.name,'TOTAL') seller_name,
case when seller.name is null then '' else sum(seller.objective) end objective,
count(sales.seller_id) as quantity
FROM seller
LEFT JOIN sales ON seller.id = sales.seller_id
WHERE seller.team_leader_id = 66
group by ROLLUP(seller.name)
order by team_leader desc, quantity desc
OR if you are okay with not using ROLLUP, you can get the exact same result using the following query.
;with cte as (
SELECT max(team_leader) team_leader,
max(name) seller_name,
max(objective) objective,
count(seller_id) as quantity
FROM seller
LEFT JOIN sales ON seller.id = sales.seller_id
WHERE seller.team_leader_id = 66
GROUP BY seller.id
)
SELECT team_leader, 'TOTAL' seller_name, '' objective, sum(quantity) quantity
FROM cte
GROUP BY team_leader
UNION ALL
SELECT '', seller_name, objective, quantity
FROM cte
Let's say I have a dataset like this (I'm using employee and manager because it's a nice example):
EmployeeID | ManagerID | Role | ...
1 | NULL | CEO
2 | 1 | Manager
3 | 1 | Manager
5 | 2 | Team-Leader
6 | 2 | Team-Leader
7 | 3 | Team-Leader
8 | 2 | Employee
9 | 5 | Employee
10 | 6 | Employee
11 | 6 | Employee
12 | 7 | Employee
I would like to list the EmployeeID's with everyone that has a role above him. This is the result I'm aiming for:
EmployeeID | ManagerID
12 | 7
12 | 3
12 | 1
12 | NULL
11 | 6
11 | 2
11 | 1
11 | NULL
....
9 | 5
9 | 2
9 | 1
9 | NULL
So if I were to use a where on the EmployeeID in the result, I could get the employee and everyone above his ranks that he's responsible to.
I tried to work it out with a recursive cte, but that didn't seem to work out at all.
Any suggestions/ideas?
Try this:
with cte1(EmployeeID, ManagerID) as
(
select EmployeeID, max(ManagerID)
from Employees
group by EmployeeID
union all
select t2.EmployeeID, t1.ManagerID
from Employees t1
join cte1 t2 on t2.ManagerID = t1.EmployeeID
)
select * from cte1
order by EmployeeID desc, ManagerID desc
I have a parent and child table like the following:
Parent Table
CourseId | CourseName
1 | MVC training
and the
Child Table
Id | StudentId | CourseId | AttnDate
1 | 33 | 1 | 6/1/2019
2 | 33 | 1 | 6/2/2019
3 | 33 | 1 | 6/3/2019
4 | 34 | 1 | 6/1/2019
5 | 34 | 1 | 6/2/2019
6 | 34 | 1 | 6/3/2019
I searched over google to use rownumber to make this but could not make it.
No idea
I want the final result like the following table. What I need is to change the 33 to 1 and 34 to 2:
Id | StudentId | CourseId | AttnDate
1 | 1 | 1 | 6/1/2019
2 | 1 | 1 | 6/2/2019
3 | 1 | 1 | 6/3/2019
4 | 2 | 1 | 6/1/2019
5 | 2 | 1 | 6/2/2019
6 | 2 | 1 | 6/3/2019
Try this using DENSE_RANK()
SELECT Id,
DENSE_RANK()OVER( ORDER BY StudentId) AS StudentId,
CourseId,
AttnDate
FROM Parent p
INNER JOIN Child c ON c.CourseId = p.CourseId
ORDER bY p.ID
Why do you need to "change the 33 to 1 and 34 to 2"? Is it for the purpose of assigning unique rank number for each distinct row within the partition (data grouped by StudentId)?
If it's true, then SQL Server DENSE_RANK ranking function is what you need
SELECT *,
DENSE_RANK() OVER(ORDER BY c.StudentId) AS RowNumberRank -- here is your rank number (StudentId in your final result)
FROM Child c
I have a question about SQL Server. I have a table something like this:
productname |Level| January | Feburary | March | total
------------x-----x-----------x----------x-------x------
Rin | L1 | 10 | 20 | 30 | 60
Rin | L2 | 5 | 10 | 10 | 25
Rin | L3 | 20 | 5 | 5 | 30
Pen | L1 | 5 | 6 | 10 | 21
Pen | L2 | 10 | 10 | 20 | 40
Pen | L3 | 30 |10 | 40 | 80
based on above table data I want output like below
productname |Level| January | Feburary | March | total
------------x-----x-----------x----------x-------x------
Rin | L1 | 10 | 20 | 30 | 60
Rin | L2 | 5 | 10 | 10 | 25
Rin | L3 | 20 | 5 | 5 | 30
RinTotal |All | 35 | 35 | 45 | 115
Pen | L1 | 5 | 6 | 10 | 21
Pen | L2 | 10 | 10 | 20 | 40
Pen | L3 | 30 | 10 | 40 | 80
PenTotal | All | 45 | 26 | 70 |141
I tried like bellow query
SELECT productname
,LEVEL
,sum(january) AS January
,sum(Feburary) AS Feburary )
,Sum(march) AS March
,Sum(total) AS total
FROM test
UNION
SELECT *
FROM test
but its not given exact output .Please point me to right direction on how to achieve this task in SQL Server.
please try this:
SELECT * FROM TEST
UNION
SELECT PRODUCTNAME+'TOTAL','ALL' AS LEVEL,SUM(JANUARY)AS JANUARY,SUM(FEBURARY)AS FEBURARY),SUM(MARCH)AS MARCH,SUM(TOTAL)AS TOTAL
FROM TEST GROUP BY PRODUCTNAME
This really belongs in the front end. Group subtotals and such are usually really simple from most reporting tools. Also, don't get lazy and use select *, you should always be explicit in your columns. Since you have a specific order I added a couple of extra columns to use for sorting.
Also don't be afraid to add some white space and formatting to your queries. It makes your life a lot easier to read and later debug.
I think something like this should get you close. Notice I changed to a UNION ALL. When using UNION it will exclude duplicates. Since you know for a fact that there are no duplicate rows a UNION ALL will eliminate the need to check for duplicates.
select productname + 'Total' as productname
, 'All' as level
, sum(january) as January
, sum(Feburary) as Feburary
, Sum(march) as March
, Sum(total) as total
, productname as SortName
, 1 as SortOrder
from test
group by productname
union ALL
select productname
, level
, January
, Feburary
, March
, Total
, productname as SortName
, 0 as SortOrder
from test
order by SortName, SortOrder
I would do this using Group by With Rollup. For more info check here
SELECT *
FROM (SELECT productname=productname + CASE WHEN level IS NULL THEN 'Total'
ELSE '' END,
Level=Isnull(level, 'ALL'),
Sum(january) AS January,
Sum(feburary) AS Feburary,
Sum(march) AS March,
Sum(total) AS total
FROM Yourtable
GROUP BY rollup ( productname, level )) a
WHERE productname IS NOT NULL
SQLFIDDLE DEMO
i am trying to find the total marks for each student based on StudentId and MarksTypeId row count.
i have 3 tables
MarksType
----------------------------------
MarksTypeId | MarkType | Marks
----------------------------------
1 | Writing | 10
2 | Drawing | 30
3 | Singing | 20
----------------------------------
Students
--------------------------------
StudentId | Name | Address
--------------------------------
1 | John | USA
2 | Raja | India
3 | Paul | AUS
--------------------------------
MarksDetails -- Has two foreign keys
-------------------------------------------------------
MarksDetailsId | MarksTypeId | StudentId | Date
-------------------------------------------------------
1 | 3 | 1 | 18 jan
2 | 3 | 1 | 18 jan
3 | 1 | 3 | 19 jan
-------------------------------------------------------
This is my Desired Result :
------------------------------------
StudentId | Name | Total Marks
------------------------------------
1 | John | 40
2 | Raja | 0
3 | Paul | 10
------------------------------------
i mean if John sang two times a day, so using StudentId and MarksTypeId, i need his total Marks as result.
so far i did the following:
select Sum(MarksType.Marks) from MarksType inner join MarksDetails on MarksType.MarksTypeId=1
but the sum returns wrong total,
UPDATED OTHER ATTEMPTS:
this results total row count for each studentid
select MarksDetails.StudentId , COUNT(MarksDetails.StudentId ) as count from MarksDetails
group by MarksDetails.StudentId
this results Marks, with studentid and markstypeid
select MarksType.Marks, MarksType.MarksTypeId , MarksDetails.StudentId from MarksType inner join MarksDetails on MarksType.MarksTypeId = MarksDetails.StudentId
may i know what i am doing wrong.
Any help would be Great.
finally with kind guidance from sql developers and after making some research, here is the query with desired result, maybe useful for someone, enjoy !
SELECT Student.StudentId, Student.Name, sum(MarksType.Marks) as TotalMarks
FROM
MarksType
INNER JOIN
MarksDetails on MarksType.MarksTypeId = MarksDetails.MarksTypeId
INNER JOIN
Student on Student.StudentId = MarksDetails.StudentId
group by Student.Name,Student.StudentId