MS access query using many tables - sql

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

Related

How to aggregate in SQL by having clause

The below is the query I'm using, I would like to add two more columns in the select statement which I have and noted them in the group by clause but the total results are different. The below script gives me the correct total count but I want to see the totals also for a column called transaction, and a column called employee. The total count should still be the same.
SELECT SUB.YEAR, SUM(SUB.TOTAL_COUNT), SUM(SUB.TOTAL_SPENT)
FROM (
SELECT YEAR, COUNT(*) AS TOTAL_COUNT, SUM($SPENTX) AS TOTAL_SPENT, CUSTOMERID
FROM TABLE A
WHERE YEAR = 2017
GROUP BY YEAR, CUSTOMERID
HAVING SUM($SPENTX)<=1000
) SUB
GROUP BY SUB.YEAR

show only user with at least one entry per month

I have two tables, let's say one is called User and the other one is called Data
Every User has many many entries in the Data table.
The Data table has the UserID and Dates included.
I would like to make a SQL query where I only get users with at least one entry per month in year 2019.
I have no idea how to do that.
You should really mention your database type. Treat this more like pseudo-code for now. But if you update your question, I can update my answer.
SELECT userID,
YEAR(Dates),
COUNT(DISTINCT MONTH(Dates))
FROM Data
WHERE YEAR(Dates) = 2019
GROUP BY UserId,
YEAR(Dates)
HAVING COUNT(DISTINCT MONTH(Dates))=12
Since you are looking only at the year 2019, you can exclude it from the GROUP BY clause. If you need to adjust the minimum entries for MONTH, I would suggest:
WITH CTE AS (
SELECT userID,
MONTH(Dates) as [month],
COUNT(*) as TotalEntriesPerMonth
FROM Data
WHERE YEAR(Dates) = 2019
GROUP BY UserId, MONTH(Dates)
HAVING COUNT(*)>=5
)
SELECT userID
FROM CTE
GROUP BY userID
HAVING COUNT([month]) = 12
Not clear what you are asking, but your query may be like below :
CREATE TABLE Data(UserId int,Dates date)
INSERT INTO Data(UserId,Dates) VALUES(1,'2020/04/28'),(1,'2020/04/29'),(2,'2020/04/29')
;WITH CTE AS (
SELECT UserId,ROW_NUMBER() OVER(PARTITION BY MONTH(Dates),UserId ORDER BY UserId) AS rn FROM Data)
SELECT Distinct UserId FROM CTE WHERE rn >=1

SQL sum output based on multiple values

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;

Return min date and corresponding amount to that distinct ID

Afternoon
I am trying to return the min value/ max values in SQL Server 2005 when I have multiple dates that are the same but the values in the Owed column are all different. I've already filtered the table down by my select statement into a temp table for a different query, when I've then tried to mirror I have all the duplicated dates that you can see below.
I now have a table that looks like:
ID| Date |Owes
-----------------
1 20110901 89
1 20110901 179
1 20110901 101
1 20110901 197
1 20110901 510
2 20111001 10
2 20111001 211
2 20111001 214
2 20111001 669
My current query:
Drop Table #Temp
Select Distinct Convert(Varchar(8), DateAdd(dd, Datediff(DD,0,DateDue),0),112)as Date
,ID
,Paid
Into #Temp
From Table
Where Paid <> '0'
Select ,Id
,Date
,Max(Owed)
,Min(Owed)
From #Temp
Group by ID, Date, Paid
Order By ID, Date, Paid
This doesn't strip out any of my dates that are the same, I'm new to SQL but I'm presuming its because my owed column has different values. I basically want to be able to pull back the first record as this will always be my minimum paid and my last record will always be my maximum owed to work out my total owed by ID.
I'm new to SQL so would like to understand what I've done wrong for my future knowledge of structuring queries?
Many Thanks
In your "select into"statement, you don't have an Owed column?
GROUP BY is the normal way you "strip out values that are the same". If you group by ID and Date, you will get one row in your result for each distinct pair of values in those two columns. Each row in the results represents ALL the rows in the underlying table, and aggregate functions like MIN, MAX, etc. can pull out values.
SELECT id, date, MAX(owes) as MaxOwes, MIN(owes) as minOwes
FROM myFavoriteTable
GROUP BY id, date
In SQL Server 2005 there are "windowing functions" that allow you to use aggregate functions on groups of records, without grouping. An example below. You will get one row for each row in the table:
SELECT id, date, owes,
MAX(Owes) over (PARTITION BY select, id) AS MaxOwes,
MIN(Owes) over (PARTITION BY select, id) AS MinOwes
FROM myfavoriteTable
If you name a column "MinOwes" it might sound like you're just fishing tho.
If you want to group by date you can't also group by ID, too, because ID is probably unique. Try:
Select ,Date
,Min(Owed) AS min_date
,Max(Owed) AS max_date
From #Temp
Group by Date
Order By Date
To get additional values from the row (your question is a bit vague there), you could utilize window functions:
SELECT DISTINCT
,Date
,first_value(ID) OVER (PARTITION BY Date ORDER BY Owed) AS min_owed_ID
,last_value(ID) OVER (PARTITION BY Date ORDER BY Owed) AS max_owed_ID
,first_value(Owed) OVER (PARTITION BY Date ORDER BY Owed) AS min_owed
,last_value(Owed) OVER (PARTITION BY Date ORDER BY Owed) AS max_owed
FROM #Temp
ORDER BY Date;

help with query in DB2

i would like your help with my query.I have a table employee.details with the following columns:
branch_name, firstname,lastname, age_float.
I want this query to list all the distinct values of the age_float
attribute, one in each row of the result table, and beside each in the second field show the
number of people in the details table who had ages less than or equal to that value.
Any ideas? Thank you!
You can use OLAP functions:
SELECT DISTINCT age_float,
COUNT(lastname) OVER(ORDER BY age_float) AS number
FROM employee_details
COUNT(lastname) OVER(ORDER BY age_float) AS number orders rows by age, and returns employees count whose age <= current row age
or a simple join:
SELECT A.age_float, count(lastname)
FROM (SELECT DISTINCT age_float FROM employee_details) A
JOIN employee_details AS ED ON ED.age_float <= A.age_float
GROUP BY A.age_float