SQL sum output based on multiple values - sql

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;

Related

How to filter out data by Dates before using a Group BY clause SQL?

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.

Add values of a column and display added result in new table

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

How do I combine these two queries?

I have 2 queries from MS Access:
Query 1:
Select Date, Username
From Table1
where Date>='9/1/2013'
group by Date, Username
After run the Query 1, I got the unique users list and run Query 2 to get the total counts:
Select Query1.Date, Count(Query1.Date)
from Query1
Where Date>='9/1/2013'
How do I translate this into SQL studio script to get unique users then count the total numbers from Date? Please advise, thank you!
Try it like this:
Select q.Date, Count(q.Date)
FROM (
Select Date, Username
From Table1
where Date>='9/1/2013'
group by Date, Username
) q
GROUP BY q.Date
There's no need for a sub query, try this:
SELECT Date, Count (date)
FROM Database.User.Table1
Where Date > '9/1/2013'
Group By date, username
Per the comments:
SELECT Date, username, Count (date)
FROM Database.User.Table1
Where Date >= '9/1/2013'
Group By date, username

How to select multiple rows in SQL Server while filling one column with the first value

Each of my rows have a date. I want the database to keep the good date. But I am in a situation where I want only the first date. But I still want all the other rows. So I would like to fill the date column with all the same date in my result.
For an example (Because I don't think I expressed myself well)
I have this:
name value date
a 10 5/13
b 14 2/13
c 20 1/13
a 11 7/13
a 5 8/13
b 8 9/13
I want it to become like this in the result:
name value date
a 26 5/13
b 22 5/13
c 20 5/13
I searched for this information but I only find the way to select the first row.
for now I'm doing
SELECT name, SUM(value), date FROM table
ORDER BY name
And I'm kind of clueless for what to do next.
Thanks :)
Databases don't have a concept of "first". Here is an attempt, but no guarantees unless you have a way of ordering to determine first:
select name, sum(value), const.date
from table cross join
(select top 1 date from table) const
group by name, const.date
If you only want to do this for a query, to provide this aggregated data for some specific client requirement, then #freshPrince's answer is appropriate. But if want to actually modify the data in the table itself, and prevent the issue from arising again, then you need to change the schema.
Create Table newTable(
name varChar(30) not null,
date datetime not null,
value decimal(10,2) not null default(0),
primary key (name, date) )
Insert newTable (name, date, value)
Select name, SUM(value), Min(date)
FROM currentTable
Group By Name
and delete the old table... then rename the new table to whatever...
You will also have to modify the process used to insert new rows so that instread of always inserting a new row, it updates the existing row for a specified name and date if it already exists...
Your question is slightly confusing since your desired result is showing a date that does not exists with either b or c but if that is the result that you want want you could use something similar to the following:
select name, sum(value) value, d.date
from yt
cross join
(
select min(date) date
from yt
where name = (select min(name)
from yt)
) d
group by name, d.date;
See SQL Fiddle with Demo
But it seems like you actually would want the min(date) for each name:
select name, sum(value) value, min(date)
from yt
group by name;
See SQL Fiddle with Demo.
If the order of the date should be the determined by the name then you could use:
select t.name, sum(value) value, d.date
from yt t
cross join
(
select top 1 name, date
from yt
order by name, date
) d
group by t.name, d.date;
See Demo

MS access query using many tables

I have a database with 12 tables with pension details of employees for Jan-Dec 2008. I want to get the total pension for 12 months for each employee adding up amounts from all the 12 tables (jan through dec).
How should I write the query?
You may want to reconsider this design, and instead have a single table with a column to indicate MONTH and YEAR.
Given your current design, your query will need to look like this (substituting your own table and field names, obviously):
First, create this query and save it as "Monthly Totals":
SELECT EmployeeId AS EmployeeNumber, SUM(Pension_Amount) AS Pension_Totals
FROM Pension_January
GROUP BY EmployeeId
UNION ALL
SELECT EmployeeId, SUM(Pension_Amount)
FROM Pension_February
GROUP BY EmployeeId
UNION ALL
.....Other months.....
UNION ALL
SELECT EmployeeId, SUM(Pension_Amount)
FROM Pension_December
GROUP BY EmployeeId;
Second, create another query that refers to the first:
SELECT
[Monthly Totals].EmployeeNumber,
SUM([Monthly Totals].Pension_Totals) AS Employee_Total
FROM [Monthly Totals]
GROUP BY [Monthly Totals].EmployeeNumber;
Now save the second query and run it. It should give you what you need.
Why on earth do you have 12 different tables? That's a fundamentally bad design.
Anyway...
Select
EmployeeID, Total2008 = Sum(Value)
From
(Select EmployeeID, Value From JanuaryTable
Union All
Select EmployeeID, Value From FebruaryTable
...
Select EmployeeID, Value From DecemberTable)
Group By
EmployeeID