Query assistance data from multiple tables - ms-access

I have 3 tables in access 2016 they are
EmployeeInformation(ID (PK), FirstName, LastName, Employee)
Trainings(TrainingID (PK), TrainingName)
CompletedTrainings(RecordID (PK), Employee, Training, Completed, Expired)
1st table Employee is a calculated field that is their first name and last name combined. 3rd table Employee and training are lookup fields from the other 2 tables and completed and expired are dates.
I want to create a query that will
-display all employees
-display all trainings
-display all completed and expired dates
-if there is an employee that did not complete a training that employee will be listed along with the training and the completed and expired date will be null.
Is this possible?

Related

MySQL Queries for a tool shop

I have to create a database for a tool shop and since I am not able to get MySQL running, because of my computer, I wanted to ask for help with my queries.
I have several entities, like customer, car, repair, repair team member, employee, service, tire storage, personal file, sales.
Now I have to do following queries:
Sort every car that contains the combination "123" inside the vehicle identification number. (Result column: VehicleID)
Here I would say SELECT * FROM Vehicle WHERE VIN = '%123%';
A list of every sales in 2021. (Result column: document number)
Here I don't know how to connect both entities (service, sales) and filter by year.
The total revenue generated from sales in 2020
An overview of all the sales to the customer with the customer ID "4711" (Result column: Date of sale, product number, price)
What about -> SELECT * FROM Verkauf WHERE Verkauf.Dienstleistung_D_ID IN ( SELECT D_ID FROM Dienstleistung WHERE Kunde_K_ID == "K4711" )
Overview of all customers who have been sold something by an employee with employment year before 2010. The output should be sorted by last name and first name of the customer. (Result columns: Customer number, first name, last name, personnel number, last name of employee, year of employment).
I hope you can help me, since I am not able to create the code, even with SQLite, MySQL etc. so I am not able to test my queries and hope that you can help me.
ER Diagram
My ER diagram is in German, I hope you understand the structure.
Reparatur - repair,
Fahrzeug - car,
Kunde - customer ,
Dienstleistung - service,
Verkauf - sales ,
Reifenlagerung - tire storage,
Reparaturteammitglied - repair team member,
Mitarbeiter - employee,
Personalakte - personal file,

Multiple Periodic Charges within a billing cycle

Each department is supposed to have only one statement per monthly billing cycle.

My goal is to figure out how many departments have been hit with more than one billing statement (having a value greater than $0.00) within the same billing cycle.  

CONTEXT: 
My current query is set to check only departments that are supposed to be billed monthly.
Department table has a one-to-many relationship with Statement table (a department is expected to have one or more statements)
Statement table has a one-to-many relationship with Trans table (a statement is expected to have one or more transactions)
Each billing statement has its own statement_close_date
c.type=‘periodic’ refers to a bill that only occurs once per billing cycle
d.period=1 represents accounts that are billed monthly
s.status=‘closed’ represents only closed statements
d.exp_date represents billing expiration date
v.status=‘active’ and d.status=‘active’ are meant to ensure that only active departments are being queried.
I also tried searching between specific expire dates on a per account basis.

The problem with my query is that it outputs the total number of billing statement_close_dates with a value greater than $0.00, instead of only checking for multiple occurrences within a billing cycle. 

How can this query be modified to only output departments with more than one instance of a bill consisting of a periodic type charge greater than $0.00 within each department’s billing cycle?  

QUERY:
SELECT s.department_id, s.statement_id, COUNT(s.statement_close_date) AS sd,
t.trans_id, from_unixtime(s.statement_close_date)
FROM statement s
INNER JOIN trans t
ON t.statement_id=s.statement_id
INNER JOIN cde c
ON t.cde=c.cde
INNER JOIN department d
ON s.department_id=d.department_id
WHERE from_unixtime(s.statement_close_date) BETWEEN
DATE_SUB(from_unixtime(d.exp_date), INTERVAL 1 MONTH) AND
from_unixtime(d.exp_date)  
AND d.period=‘1’
AND s.status='closed'
AND t.dollars>0
AND c.type='periodic'
GROUP BY s.statement_id DESC
HAVING sd>1
SAMPLE OUTPUT:
department_id statement_id sd trans_id statement_close_date
1719712 9351464 3 98403043 2018-09-24
1719709 9351463 2 98403026 2018-09-24
1719708 9351462 2 98403010 2018-09-24
1719665 9351457 3 97374764 2018-09-24

SQL report that includes sales rep, sales rep's state, and the total sales for that sales rep's state ordered by YYY-MM

The situation. I am trying to make a report that lists the sales rep names (all of them; there are 50), the sales rep's state, and the total sales broken down by YYYY-MM for that state. If there are two or more sales reps in the state, they should each be listed with the same information for their state. How the final list is ordered does not matter, so long as all the information is included.
The problem. I also need totals by state in addition to the totals I have.
Here is my code:
SELECT
dim_sales_rep.sales_rep_name as 'Sales Rep',
dim_state.abbreviation as 'State',
date_format(dim_date.date, '%Y-%m') as 'Year-Month',
concat('$',sum(fact_sales.total_sales)) as 'Sales'
FROM
(
(
dim_sales_rep
JOIN dim_state ON dim_sales_rep.state_key = dim_state.state_key
)
JOIN fact_sales ON dim_sales_rep.sales_rep_key = fact_sales.sales_rep_key
)
JOIN dim_date ON fact_sales.date_key = dim_date.date_key
GROUP BY dim_date.year, dim_date.month, dim_state.abbreviation, dim_sales_rep.sales_rep_name
Sample Output:
Rep State Year-Month Sales
Michele Harris GA 2010-08 $679.79
T.S. Eliot GA 2010-07 $2938.74
It should look like this:
Rep State Year-Month Sales
Michele Harris GA 2010-08 $679.79
Georgiana Woe GA 2010-08 $482.98
State total $1162.77
Or like this:
Rep State Year-Month YM Total State Total
Michaele Harris GA 2010-08 $679.79 $1162.77
Georgiana Woe GA 2010-08 $482.98 $1162.77
Here is the data structure:
table fact_sales
date_key (PK) Surrogate Key
account_key (PK) Surrogate Key
sales_rep_key (PK) Surrogate Key
total_sales Total sales dollars.
count_of_products Number of products sold
table dim_state
state_key (PK) Surrogate Key
abbreviation e.g. AL or CA
name e.g. California
table dim_account
account_key (PK) Surrogate Key
account_name
account_address
state_key Surrogate Key
effective_date Starting date that this record is active
expiration_date Ending date that this record is active
is_current Represents the active record
table dim_sales_rep
sales_rep_key (PK) Surrogate Key
sales_rep_name
state_key Surrogate Key
effective_date Starting date that this record is active
expiration_date Ending date that this record is active
is_current Represents the active record
table dim_date
date_key (PK) Surrogate Key date e.g. 2011-01-01
month e.g. 01
year e.g. 2011
Notes:
PK: Denotes that the column is the primary key or is part of the primary key of the table.
Surrogate Keys are represented as numeric and do not represent actual values from an application. For example date_key could be 1,2,3,4, etc. and is not a real date.
Assume that dim_date contains all dates for all time.
Assume that if the column has the same name in a different table that they are equivalent.
When you group by just the state, you get one row per state in your result set. That's what GROUP BY means: aggregate your data broken out by the column values it mentions.
Use this:
GROUP BY dim_date.year, dim_date.month, dim_state.abbreviation, dim_sales_rep.sales_rep_name WITH ROLLUP
And, formatting your dates well can be done using MySQL's date functions.
Try this:
SELECT DATE_FORMAT(STR_TO_DATE(CONCAT_WS('-',2014,3,1),'%Y-%m-%e'),'%Y-%m')

Another SQL-Interrogation

I've got another problem on my SQL Tables but this time I've got more tables linked together.
What I realised and where I'm stuck:
I have tables about jobs, wages, employees.
I've done a query with these conditions:
The employee with the biggest wage in my company:
select employee_id, count(employee) as wage
from number_statistics
group by employee_id
having count(employee_id) in
(select max(count(employee_id)) from number_statistics group by employee_id);
This will show the ID of my employee with the biggest wage.
Where I'm stuck:
My next task is to create this query:
I need to display the employee with the biggest wage on three age categories:
Between 21-30; 30-45; 45-60;
The problem is that I don't have a field name AGE (and I'm not allowed to use one) in my tables.
I only have the birth date of my employees.
While I don't know the fully answer to this, I think your solution involves the function
TIMESTAMPDIFF(YEAR,birthdate,curdate()) BETWEEN 21 AND 30
This returns results that have between 21 and 30 years.

Database schema for efficient attendance management system

I am developing an attendance system for school which will cater to both employees as well as students.
The current db schema is
attendance table
id - primary key for this table
daydate int(11) - stores timestamp of current day
timing_in varchar(18) - Start time for institution
timing_out - Closing time for institution
status - Status for the day, can be working day - 1 or holiday - 2
Then there are different tables for staff & students, which store the actual attendance values.
For staff, the attendance is stored in attendance_staff. The database schema is
attendance_id - foreign key, references attendance table
staff_id - id of staff member, references staff master table
time_in - stores in timing of a staff member
time_out - stores out timing of a staff member
status - attendance status - can be one among the list, like present, absent, casual leave, half day, late mark, on duty, maternity leave, medical leave etc
For staff, i am storing both present as well as not present entries in the table.
Now attendance for students has to be included with it.
Since status of each day is already stored in attendance table, can we store not present values for each student in the student attendance table.
Like, the student attendance table will store only entries for those days who are not present on a particular day.
The schema for attendance_student will be
attendance_id - references attendance table
student_id - references student table
status - will be leave / absent etc other than present.
Will it be efficient to calculate the present days from attendance table using outer join??
Thanks in advance.
You don't need an outer join to calculate attendance for students. You could simply count the records in your attendance table (one time, since it would be the same for all students) and then just select from your student attendance table to get absences.
If you'd prefer to count attendance with an outer join you could. It is likely to be more than efficient enough if you have an index on your attendance table primary key and on the foreign key from student attendance table to your attendance table.