How do i do these queries? - mysql

I am trying to do these queries for a homework of a subject that the teacher didn't teach us, and none of my classmates can do it either, I have these 4 tables to MySQL
Activity
idActivity | nameActivity | idDepartment
---------: | :--------------------- | -----------:
1 | hiring | 1
2 | payroll | 1
3 | purchasing | 2
4 | quotes | 2
5 | Customer contact | 3
6 | Customer agreement | 3
7 | marketing | 3
8 | Product placement | 2
9 | Collection of products | 2
10 | assitance | 1
11 | Product delivery | 3
12 | Check-in and check-out | 4
13 | offers | 3
Employee
idEmployee | NameEmployee | Salary | idDepartment
---------: | :----------- | -----: | -----------:
10 | Maria | 4000 | 1
20 | Jorge | 3000 | 2
30 | Leonor | 5000 | 3
40 | Patricia | 3000 | 2
50 | Gilberto | 2000 | 4
60 | Gonzalo | 7000 | 2
70 | Beatriz | 3000 | 1
80 | Ana | 5000 | 3
90 | Manuel | 2000 | 4
100 | Silvestre | 7000 | 1
110 | Alejandra | 5000 | 2
120 | Fernando | 2000 | 1
130 | Joaquin | 4000 | 4
140 | Pedro | 4000 | 4
150 | Pablo | 2500 | 3
Department
idDepartment | nameDepartment
-----------: | :-------------
1 | staff
2 | Purchasing
3 | Sells
4 | finances
Activity-Employee
idEmployee | idActivity
---------: | ---------:
10 | 1
10 | 2
20 | 3
20 | 4
30 | 5
30 | 6
30 | 7
50 | 8
50 | 9
70 | 10
90 | 8
100 | 1
db<>fiddle here
Some columns have the same name because primary and foreign keys, the primary keys are in the tables that have there names. What am I trying to do are some queries like:
Show employees names, name of the department that they belong to, and name of the activities that they do, grouping by activity (Group by).
Using Subqueries Show employees names, name of the department that they belong to, and name of the activities that they do, grouping by activity (Group by).
We tried some queries but the employee name just repeat itself, and didn't group by activities.
https://drive.google.com/file/d/1f7AkdjHYltKxg640diUZfD2zs2gM-sol/view?usp=sharing
Hopefully someone can help us, we are kinda desperate :(
And sorry for not knowing how to put directly the tables in here, it's my first post in here:(

select
NameEmployee,
group_concat(nameActivity) nameActivity,
(select nameDepartment from Department where idDepartment=tmpx.idDepartment) as DeptName from (select t1.NameEmployee,
(select distinct nameActivity from Activity where idActivity=t2.idActivity) as nameActivity,
(select distinct idDepartment from Activity where idActivity=t2.idActivity) as idDepartment
from Employee t1 join `Activity-Employee` t2
on t1.idEmployee=t2.idEmployee) as tmpx GROUP BY tmpx.NameEmployee;
Check if it works for u

Related

GROUP sum BY two tables by joining

I'm trying to write a SQL query that will correctly group sales items sold_qyt and sub-total-price together as per product's category so I can show this on the printable invoice that product from Jelly Sheet = 4 at a rate of 62 subtotal for this category product is 248(4 * 62 = 248). but when I try to run the below-mentioned query it shows out-put as 12 but I want subtotal and sold_qyt segregated base on category.
I have tried to run different queries just one query gives the output which is mentioned below and this is for just the sum of all sold_qyt. DB example is also shown below
DB Example: (For better understanding)
Table # 1:
Category
ID | code | name
1 | 1 | jelly sheet
2 | 2 | 9D Glass
3 | 3 | Polished Glass
Table # 2:
Product:
ID | code | name | cost | category_id | price
1 | 1 | IP11JS | 50 | 1 | 62
2 | 2 | IP12JS | 50 | 1 | 62
3 | 3 | IP119D | 40 | 2 | 55
4 | 4 | IP129D | 40 | 2 | 55
5 | 5 | IP11PG | 18 | 3 | 25
6 | 6 | IP12PG | 18 | 3 | 25
Table # 3:
sale_items:
ID | sale_id | product_id | product_code | product_name | unit_price | sold_qyt | subtotal |
1 | 1 | 1 | 1 | IP11JS | 62 | 2 | 124 |
2 | 1 | 2 | 2 | IP12JS | 62 | 2 | 124 |
3 | 1 | 3 | 3 | IP119D | 55 | 2 | 110 |
4 | 1 | 4 | 4 | IP129D | 55 | 2 | 110 |
5 | 1 | 5 | 5 | IP11PG | 25 | 2 | 50 |
6 | 1 | 6 | 6 | IP12PG | 25 | 2 | 50 |
7 | 2 | 7 | 1 | IP11JS | 62 | 2 | 124 |
8 | 2 | 8 | 2 | IP12JS | 62 | 2 | 124 |
9 | 2 | 9 | 3 | IP119D | 55 | 2 | 110 |
10 | 2 | 10 | 4 | IP129D | 55 | 2 | 110 |
11 | 2 | 11 | 5 | IP11PG | 25 | 2 | 50 |
12 | 2 | 12 | 6 | IP12PG | 25 | 2 | 50 |
SQL Query which is run by me:
SELECT sale_id,
SUM(sold_qyt) AS sold_qyt
FROM sale_items
GROUP BY sale_id
kindly help me with this difficulty thanks in advance
Update: 1-21-2021
i execute new query
SELECT (sma_sale_items.sale_id, sma_categories.code AS sma_products.category_id, sma_products.code AS sma_sale_items.product_code,)
SUM(sold_qyt) AS sold_qyt
SUM(subtotal) AS subtotal
FROM sma_sale_items
LEFT JOIN sma_products ON sma_products.id=sma_sale_items.product_id
LEFT JOIN sma_categories ON sma_categories.code=sma_products.category_id
GROUP BY sma_sale_items.sale_id
ORDER BY sma_categories
but no luck :(
I want the output like this:
Expected OUT PUT:
ID | sale_id | category_name | sold_qyt | subtotal |
1 | 1 | Jelly Sheet | 4 | 248 |
2 | 1 | 9D Glass | 4 | 220 |
3 | 1 | Polished Glass | 4 | 100 |
4 | 2 | Jelly Sheet | 4 | 248 |
5 | 2 | 9D Glass | 4 | 220 |
6 | 2 | Polished Glass | 4 | 100 |
The ID column in your expected result set is very misleading - it appears to be just new ID value for the output result set rather than any of the ID values from the source tables.
If it is important for you then you can use this query:
SELECT ROW_NUMBER() OVER (ORDER BY sale_id, category_id),
sale_id,
category_name,
sold_qty,
subtotal
FROM (
SELECT c.ID as category_id,
si.sale_id,
c.[name] as category_name,
SUM(si.sold_qty) as sold_qty,
SUM(si.subtotal) as subtotal
FROM sale_items si
JOIN product p ON p.ID = si.product_code
JOIN category c ON c.ID = p.category_id
GROUP BY c.ID,
si.sale_id,
c.[name]
) r
If it is not relevant and you only want the sale_id, category_name and the totals then simplify it to:
SELECT si.sale_id,
c.[name] as category_name,
SUM(si.sold_qty) as sold_qty,
SUM(si.subtotal) as subtotal
FROM sale_items si
JOIN product p ON p.ID = si.product_code
JOIN category c ON c.ID = p.category_id
GROUP BY si.sale_id,
c.[name]
ORDER BY sale_id, category_name

Converting lump sums to transactions

I have a database that tracks the size of claims.
Each claim has fixed information that is stored in claim (such as claim_id and date_reported_to_insurer).
Each month, I get a report which is added to the table claim_month. This includes fields such as claim_id, month_id [101 is 31/01/2018, 102 is 28/02/2018, etc] and paid_to_date.
Since most claims don't change from month to month, I only add a record for claim_month when the figure has changed since last month. As such, a claim may have a June report and an August report, but not a July report. This would be because the amount paid to date increased in June and August, but not July.
The problem that I have now is that I want to be able to check the amount paid each month.
Consider the following example data:
+----------------+----------+----------------+--------------+
| claim_month_id | claim_id | month_id | paid_to_date |
+----------------+----------+----------------+--------------+
| 1 | 1 | 6 | 1000 |
+----------------+----------+----------------+--------------+
| 5 | 1 | 7 | 1200 |
+----------------+----------+----------------+--------------+
| 7 | 2 | 6 | 500 |
+----------------+----------+----------------+--------------+
| 12 | 1 | 9 | 1400 |
+----------------+----------+----------------+--------------+
| 18 | 2 | 8 | 600 |
+----------------+----------+----------------+--------------+
If we assume that this is all of the information regarding claim 1 and 2, then that would suggest that they are both claims that occurred during June 2018. Their transactions should look like the following:
+----------------+----------+----------------+------------+
| claim_month_id | claim_id | month_id | paid_month |
+----------------+----------+----------------+------------+
| 1 | 1 | 6 | 1000 |
+----------------+----------+----------------+------------+
| 5 | 1 | 7 | 200 |
+----------------+----------+----------------+------------+
| 7 | 2 | 6 | 500 |
+----------------+----------+----------------+------------+
| 12 | 1 | 9 | 200 |
+----------------+----------+----------------+------------+
| 18 | 2 | 8 | 100 |
+----------------+----------+----------------+------------+
The algorithm I'm using for this is
SELECT claim_month_id,
month_id,
claim_id,
new.paid_to_date - old.paid_to_date AS paid_to_date_change,
FROM claim_month AS new
LEFT JOIN claim_month AS old
ON new.claim_id = old.claim_id
AND ( new.month_id > old.month_id
OR old.month_id IS NULL )
GROUP BY new.claim_month_id
HAVING old.month_id = Max(old.month_id)
However this has two issues:
It seems really inefficient at dealing with claims with multiple
records. I haven't run any benchmarking, but it's pretty obvious.
It doesn't show new claims. In the above example, it would only show lines 2, 3 and 5.
Where am I going wrong with my algorithm, and is there a better logic to use to do this?
Use LAG function to get the next paid_to_date of each claim_id, and use the current paid_to_date minus the next paid_to_date.
SELECT
claim_month_id,
claim_id,
month_id,
paid_to_date - LAG(paid_to_date, 1, 0) OVER (PARTITION BY claim_id ORDER BY month_id) AS paid_month
FROM claim
The output table is:
+----------------+----------+----------+------------+
| claim_month_id | claim_id | month_id | paid_month |
+----------------+----------+----------+------------+
| 1 | 1 | 6 | 1000 |
| 5 | 1 | 7 | 200 |
| 12 | 1 | 9 | 200 |
| 7 | 2 | 6 | 500 |
| 18 | 2 | 8 | 100 |
+----------------+----------+----------+------------+

MS Access - display repeating rows once with the highest value

I have 2 tables in MS Access with the following values
Customer
id | name
1 | jon
2 | bob
3 | jack
Order
id | amount | date | customer
5 | 50 | 3/10/2017 | 1
4 | 100 | 3/10/2017 | 1
3 | 45 | 2/28/2017 | 2
2 | 10 | 3/10/2017 | 3
1 | 5 | 3/10/2017 | 2
I want to get an output of
name | orderid | amount
jon | 5 | 50
bob | 3 | 45
jack | 2 | 10
I want to get amount of the latest order id per customer, however I keep getting this
name | orderid | amount
jon | 5 | 50
jon | 4 | 100
bob | 3 | 45
bob | 2 | 10
jack | 1 | 5
I used the query designer and have used the function MAX() to the order id, GROUP BY to all columns (MS Access does not allow to group the rows using a single column), DISTINCT and DISTINCTROW, as well as set the query properties "Unique Records" to Yes but the duplicate records still shows.

mysql query using inner joins and subquery

These are the tables:
professor:
+-------+--------+--------+--------+------+
| empid | name | status | salary | age |
+-------+--------+--------+--------+------+
| 1 | Arun | 1 | 2000 | 23 |
| 2 | Benoy | 0 | 3000 | 25 |
| 3 | Chacko | 1 | 1000 | 36 |
| 4 | Divin | 0 | 5000 | 32 |
| 5 | Edwin | 1 | 2500 | 55 |
| 7 | George | 0 | 1500 | 46 |
+-------+--------+--------+--------+------+
works:
+----------+-------+---------+
| courseid | empid | classid |
+----------+-------+---------+
| 1 | 1 | 10 |
| 2 | 2 | 9 |
| 3 | 3 | 8 |
| 4 | 4 | 10 |
| 5 | 5 | 9 |
| 6 | 1 | 9 |
| 2 | 3 | 10 |
| 2 | 1 | 7 |
+----------+-------+---------+
course:
+----------+------------+--------+
| courseid | coursename | points |
+----------+------------+--------+
| 1 | Maths | 100 |
| 2 | Science | 80 |
| 3 | English | 85 |
| 4 | Social | 90 |
| 5 | Malayalam | 99 |
| 6 | Arts | 40 |
+----------+------------+--------+
The question is :
Return list of employees who have taught course Maths or Science but
not both
The query which I wrote is :
select distinct professor.name from professor
inner join works
on professor.empid=works.empid
where works.courseid in
(select courseid from course where coursename ='Maths' or coursename='Science');
The output I received is:
Arun
Benoy
Chacko
Here the employee 'Arun' shouldnt have been displayed as he as taught both Maths and Science.
Please help me out !!
You may use an aggregate COUNT() to check that the total number of DISTINCT courses taught is exactly 1, while still filtering to the two different types of courses. That ensures that only one, never both, is returned.
Because the IN () limits all rows initially returned only to the two desired courses, professors can have a maximum of 2 possible different courses via COUNT(DISTINCT coursename). A HAVING clause then prohibits those with 2 from the final result set.
SELECT
DISTINCT professor.name
FROM
professor
INNER JOIN works ON professor.empid = works.empid
/* Join against course to get the course names */
INNER JOIN course ON works.courseid = course.courseid
WHERE
/* Restrict only to Maths, Science */
course.coursename IN ('Maths', 'Science')
GROUP BY professor.name
/* Only those with exactly one type of course */
HAVING COUNT(DISTINCT course.coursename) = 1
Here is a demonstration: http://sqlfiddle.com/#!2/2e9610/2
You want to use an xor here instead of an or.
select distinct professor.name from professor
inner join works
on professor.empid=works.empid
where works.courseid in
(select courseid from course where coursename ='Maths' xor coursename='Science');

MySql query to perform join between 2 tables

These are the tables:
professor
+-------+--------+--------+--------+------+
| empid | name | status | salary | age |
+-------+--------+--------+--------+------+
| 1 | Arun | 1 | 2000 | 23 |
| 2 | Benoy | 0 | 3000 | 25 |
| 3 | Chacko | 1 | 1000 | 36 |
| 4 | Divin | 0 | 5000 | 32 |
| 5 | Edwin | 1 | 2500 | 55 |
| 7 | George | 0 | 1500 | 46 |
+-------+--------+--------+--------+------+
works
+----------+-------+---------+
| courseid | empid | classid |
+----------+-------+---------+
| 1 | 1 | 10 |
| 2 | 2 | 9 |
| 3 | 3 | 8 |
| 4 | 4 | 10 |
| 5 | 5 | 9 |
| 6 | 1 | 9 |
+----------+-------+---------+
The above are the tables from which I need to retrieve the data from.
The question is to return list of Employees who take both Class 10 and
Class 9.
The query I have written is:
select professor.name
from inner join works
on professor.empid=works.empid
where works.classid=9 and works.classid=10;
I know that the result I want is Arun, but I don't know what should be the exact query to retrieve the required result.
He wants the professeors that take class 9 AND 10. So there are 2 different records in works that need to match.
select professor.name from professor
join works A on A.empid=professor.empid and A.classid=9
join works B on B.empid=professor.empid and B.classid=10
See http://sqlfiddle.com/#!2/4be88a/1
Try This
select professor.name
from professor inner join works
on professor.empid=works.empid
where works.classid=9 OR works.classid=10;
(OR)
select professor.name
from professor inner join works
on professor.empid=works.empid
where works.classid IN ('9','10')
SELECT prof.name FROM professor AS prof
JOIN works
ON prof.empid = works.empid
WHERE works.classid IN (9, 10);