The table with the data that I have
In the above table I have the columns : weekNumber , weeklyHours , points_Rewarded.
There are four employees : a,b,c,d
I have the values for week1,week2,week3, and so on ( I can have data for many more weeks also such as week4,week5, etc)
I want to write a query such that after passing the query I get the total of the weeklyHours and points_Rewarded for each employee in a new table.
The kind of table that the query should give me is here the desired table that I want after passing the query
Please help me with the query.
Thanks in advance.
You can use GROUP BY to achieve aggregate values. In your case your are looking for SUM.
Try this
DECLARE #tbl TABLE(EmployeeID INT, EmployeeName VARCHAR(100),WeekNumber VARCHAR(100),WeeklyHours INT,pointsRewarded INT);
INSERT INTO #tbl VALUES
(1,'a','week1',10,20)
,(2,'b','week1',1,20)
,(3,'c','week1',20,20)
,(4,'d','week1',30,30)
,(1,'a','week2',11,10)
,(2,'b','week2',44,10)
,(3,'c','week2',5,10)
,(4,'d','week2',6,40)
,(1,'a','week3',7,10)
,(2,'b','week3',88,10)
,(3,'c','week3',9,10)
,(4,'d','week3',0,10);
SELECT tbl.EmployeeID
,tbl.EmployeeName
,SUM(tbl.WeeklyHours) AS Total_Weekly_Hours
,SUM(pointsRewarded) AS Total_Points
FROM #tbl AS tbl
GROUP BY tbl.EmployeeID, tbl.EmployeeName
Try with the below query.
SELECT EmployeeName
,SUM (weeklyHours)Total_weekly_hours
,SUM (pointsrewarded) TotalPoints
FROM YourTable
Group By EmployeeName
This is a simple GROUP BY. You want to group the employees by name so specify employeename in the GROUP BY statement. Then just select HOW you want to group the other columns. In this case, you want to SUMthem:
SELECT employeename,
SUM(weeklyhours) as total_weekly_hours,
SUM(points_rewarded) as total_points
GROUP BY employeename
Note that you could also use AVG or MIN or MAX in place of SUM depending on what you want to find. The AS clause specifies what you want to call a particular column in your output.
Tested here: http://sqlfiddle.com/#!9/2a96f
Related
So I have a data that looks similar like below:
CREATE TABLE EXAMPLE (
PERSONID int,
Diagnosis varchar(255),
AdmissionDate date
)
INSERT INTO EXAMPLE
VALUES
('1','Broken Bone','2019-12-01'),
('2','Headache','2019-12-02'),
('3','Cancer','2020-01-05'),
('4','Broken Bone','2020-02-01'),
('5','Broken Bone','2020-03-01'),
('6','Headache','2020-03-06'),
('7','Cancer','2020-04-05')
I am trying to use a group by clause like below:
SELECT
Diagnosis,
COUNT(*) AS NumberOfDiagnosis
FROM EXAMPLE
GROUP BY Diagnosis
However, I would like to only select the group by clause on data that has an admission date before 2020-03-1. I have an understanding that I should use a subquery or nested queries but I am not sure how to execute that. My Desired Output is something like the table below:
Diagnosis
NumberOfDiagnosis
Broken Bone
2
Headache
1
cancer
1
Just use a where clause
SELECT
Diagnosis,
COUNT(*) AS NumberOfDiagnosis
FROM EXAMPLE
where AdmissionDate<'2020-03-01'
GROUP BY Diagnosis
I think you just want a where clause:
SELECT Diagnosis, COUNT(*) AS NumberOfDiagnosis
FROM EXAMPLE
WHERE AdmissionDate < '2020-03-01'
GROUP BY Diagnosis;
This filters the data before aggregation so only records before that date are included in the result set.
I have two tables that I was going to join, but I understand it's more efficient to use CREATE VIEW. This is what I have:
CREATE OR REPLACE VIEW view0_joinedTablesGrouped
AS
Select table1.*,table2.*
FROM table1
inner join table2 on table1.col =
table2.matchingcol
group by table2.matchingcol;
which causes the following error:
ERROR: column "table1.col" must appear in the GROUP BY clause or be
used in an aggregate function
LINE 3: Select table.*,table2.*
Group By cannot do what you are trying to do.
Consider a simple table:
Name Age
-------
Ann 10
Bill 10
Chris 11
If you try to group by age with:
Select * from Table group by Age
What, exactly, do you expect to appear in the Name column for Age=10? Ann, or Bill or both or neither or ....? There is no good answer.
So, when you group by, every column in the output has to be an aggregate – that means a function of every row in the group.
So these are valid:
Select Age, Count(*) from Table group by Age
Select Age, Max( Length(Name)) from Table group by Age
Select Age, Max(Name) from Table group by Age
But this is impossible to do, and isn't valid:
Select Age,Name from Table group by Age
So your select * is the problem -- you can't just select column values because when you group by there's a whole group of column values for every output row, and you can't stuff all those values into one column of one row.
As for using a view, #systemjack's comment is correct.
I have this query :
select resorti.resort_id
,resorti.resort
,hoteli.resort_id
,hoteli.hotel_id
,hoteli.hotel
from resorti
inner join
hoteli on resorti.resort_id = hoteli.resort_id
How do I change this query so that the name of the resort is listed only once if there are many resorts with the same name ?
Edit: I altered the query. Here are the actual results :
Here are the desired results:
You can group by the resort info but you'll lose the detail you want on the hotels.
Truly you are better suppressing the "duplicate" resort entry in you application layer.
You could generate row number within each group in a derived table and then query that suppressing the resort when row number <> 1, but the syntax would depend on your rdbms.
Edit:
against my better judgement, here's how you could do it in sql sever. same is possible without tsql's row_number or a cte, it's just more concise.
create table resorti (resort_id INT, resort VARCHAR(50))
create table hoteli (hotel_id INT, resort_id INT, hotel VARCHAR(50))
insert into resorti values (1,'resort_1'),(2,'resort_2')
insert into hoteli values (1,1,'hotel_1a'),(2,1,'hotel_1b'), (3,2,'hotel_2a'),(4,2,'hotel_2b')
;with cte as (
SELECT *
,ROW_NUMBER() OVER (PARTITION BY resort_id ORDER BY hotel_id) rn
FROM hoteli
)
select case when rn=1 then resorti.resort_id end resort_id
,case when rn=1 then resorti.resort end resort
,resorti.resort
,cte.hotel_id
,cte.hotel
from resorti
inner join
cte on resorti.resort_id = cte.resort_id
Please give more information of your database... If you group by resort and there are two rows with same name but different resort_id then a group is only possible if you don't select the resort_id. Or your second selected column of table resorti is calculated by one of these functions: SUM, AVG, MAX, MIN, and COUNT
Try something like this
SELECT
resorti.resort,
hoteli.hotel_id,
hoteli.hotel
FROM resorti
INNER JOIN hoteli ON resorti.resort_id = hoteli.resort_id
GROUP BY resorti.resort
How can I get an output that shows the sum(hours) for multiple names in this table with one sql command?
Ideal output would for example (20, 70) based on the below table which would be the sum hours for each person on that date.
Current SQL.
SELECT sum(hours) from project_time where date = '04/07/2013' AND name = 'Rhys Parker'
The above sql give the result I want but its only for one users, I would like to get the output for all users on that date.
DB table:
DB Structure: SQLITE
CREATE TABLE PROJECT_TIME ( name VARCHAR(16), date DATE, project VARCHAR(16), hours VARCHAR(16), PRIMARY KEY (name, project, date))
You will add a GROUP BY. Using the aggregate function along with the GROUP BY will give you a result for each DISTINCT name you have the in the table:
SELECT name, sum(hours) TotalHours
from project_time
where date = '04/07/2013'
GROUP BY name
See SQL Fiddle with Demo
Sounds like you should be using GROUP BY:
SELECT name, sum(hours)
FROM project_time
WHERE date = '04/07/2013'
GROUP BY name
This will get you the sum of hours for each name:
Rhys Parker 70
Bob Smith 20
SQL Fiddle Demo
You want a group by:
SELECT name, sum(hours)
from project_time
where date = '04/07/2013'
group by name
Just to give an alternative, if you want it for all the dates, do
SELECT name,date, sum(hours) as TotalHours
from project_time
GROUP BY name,date;
I have the below example:
SELECT name, age, location, SUM(pay)
FROM employee
GROUP BY location
This as expected will give me an error:
ORA-00979: not a GROUP BY expression
How can I get around this? I need to group by one maybe two columns but need to return all columns even if they're not used in the GROUP BY clause, I've looked at sub-queries to get around it but have had no luck so far.
You can use analytic functions:
SELECT name
, age
, location
, pay
, SUM(pay) over (partition by location order by location ) total
FROM employee
So, you can return all rows even if they are not used in the grouping.
So you want to know the total pay by location, and you want to know the names and ages of employees at each location? How about:
SELECT e.NAME,
e.AGE,
e.LOCATION,
t.TOTAL_LOCATION_PAY
FROM EMPLOYEE e
INNER JOIN (SELECT LOCATION,
SUM(PAY) AS TOTAL_LOCATION_PAY
FROM EMPLOYEE
GROUP BY LOCATION) t
ON (t.LOCATION = e.LOCATION)
Share and enjoy.
(Group b[http://docs.oracle.com/javadb/10.6.2.1/ref/rrefsqlj32654.html] Must have an aggregate function in every column that is not in the group by clause. When you are grouping, means that you want one row per group. Distinct values of the columns in the clause appear in the final result set.
This is because oracle can't know which of the values for the column that you don't have in the group by to retrieve. Consider this:
A X
B X
Select col1, col2 from myTable group by col2; -- incorrect
Select min(col1), col2 from myTable group by col2; -- correct
Why is the first incorrect? Because oracle can't know whether to retrieve A or B for the X value you have to specify it. i.e. MIN, MAX, etc.
There is an alternative to this named analytic functions that allow you to work under windows of your result set.
Now if you want total employee pay by location, and every employee you may want this.
SELECT name, age, location, SUM(pay) OVER(PARTITION BY location)
FROM employee
I believe this is better than #Bob Jarvis query as you only query the table once. Please correct me if I'm wrong. He also has employees and employee. Typo?