Join 2 query in different as different column - mysql

I need to join 2 queries within a database but place it in 2 different column
i tried union but the result are in the same column "total fulltime"
(SELECT (SUM(servicehours) + SUM(`teachinghours`) + SUM(`researchhours`)) as 'Total fulltime'
FROM staff_hour sh,staff s,role r
WHERE r.roleid =s.roleid
AND s.staffid = sh.staffid
AND r.roleid='2'
AND sh.staffperiodyear = 'FY2018')
union
(SELECT (SUM(servicehours) + SUM(`teachinghours`) + SUM(`researchhours`)) as 'Total parttime'
FROM staff_hour sh,staff s,role r
WHERE r.roleid =s.roleid
AND s.staffid = sh.staffid
AND r.roleid='3'
AND sh.staffperiodyear = 'FY2018')
How do i join it so that there are 2 different column('total fulltime' & 'total parttime') with the total sum?

You could use your queries with cross join
select t1.Total_fulltime
, t2.Total_parttime
, t1.Total_fulltime + t2.Total_parttime total_sum
from (SELECT (SUM(servicehours) + SUM(`teachinghours`) + SUM(`researchhours`)) as Total_fulltime
FROM staff_hour sh,staff s,role r
WHERE r.roleid =s.roleid
AND s.staffid = sh.staffid
AND r.roleid='2'
AND sh.staffperiodyear = 'FY2018') t1
CROSS JOIN
(SELECT (SUM(servicehours) + SUM(`teachinghours`) + SUM(`researchhours`)) as Total_parttime
FROM staff_hour sh,staff s,role r
WHERE r.roleid =s.roleid
AND s.staffid = sh.staffid
AND r.roleid='3'
AND sh.staffperiodyear = 'FY2018') t2

Related

GROUP_CONCAT multiple where condition particular data

Query
(SELECT
pid,
visitdate,
GROUP_CONCAT(tooth, ' - ', problem, ' - ', recomendation SEPARATOR ', <br>')
FROM tbl_finds_d) V
WHERE V.pid='1' AND V.visitdate = '16-03-2020'
TABLE
Want to get WHERE pid=1 AND visitdate=16-03-2020
pid visitdate tooth problem recomendation
1 16-03-2020 13 ASX DFFF
1 16-03-2020 12 JHJ HJLP
2 12-03-2020 14 JKB IJLHJ
UPDATE (copied from the comment)
SELECT *
FROM pendingtreatment A
INNER JOIN tbl_finds_m B ON B.pid = '$pid'
AND B.visitdate = '$visitdate'
INNER JOIN treatmentadviced C ON C.pid = '$pid'
AND C.visitdate = '$visitdate'
INNER JOIN treatmentlist D ON D.pid = '$pid'
AND D.visitdate = '$visitdate'
INNER JOIN tbl_appointments E ON E.pid = '$pid'
AND E.visitdate = '$visitdate'
INNER JOIN ( SELECT pid,
visitdate,
GROUP_CONCAT(tooth, ' - ', problem, ' - ', recomendation SEPARATOR ', <br>')
FROM tbl_finds_d V
WHERE V.pid='$pid'
AND V.visitdate = '$visitdate') F
WHERE A.pid = '$pid'
AND A.visitdate = '$visitdate'

How do I display two columns with multiple values and separate the occurances with a WHERE clause

This is my SQL query I am trying to select the names of employees from the employee table 'T' as trainer and 'S' as student. Where each student is linked to a trainer.
SQL query:
SELECT
cc.CourseName,
FORMAT(cs.StartDate, 'dd/MM/yyyy') AS 'Start Date',
FORMAT(cs.EndDate, 'dd/MM/yyyy') AS 'End Date',
a.AcademyName,
r.RoomName,
(SELECT e.FirstName + ' ' + e.LastName WHERE e.EmployeeType = 'T') AS 'Trainer',
(SELECT e.FirstName + ' ' + e.LastName WHERE e.EmployeeType = 'S') AS 'Student'
FROM
Employees e
INNER JOIN
CourseScheduleTrainers cst ON e.EmployeeID = cst.EmployeeID
INNER JOIN
CourseScheduleAttendees csa ON cst.TrainerID = csa.TrainerID
INNER JOIN
CourseCatalog cc ON csa.CourseCatalogID = cc.CourseCatalogID
INNER JOIN
CourseSchedule cs ON cc.CourseScheduleID = cs.CourseScheduleID
INNER JOIN
Rooms r ON cs.RoomsID = r.RoomsID
INNER JOIN
Academies a ON r.AcademyID = a.AcademyID;
This is what it is returning:
And this is an ERD of the database I am am trying to create. Essentially Course Attendees can also be classed as employees and they are labelled using the Employee Type
Entity Relationship Diagram:
I thought it was a simple case of sub querying but that doesn't seem to work.
Consider joining Employees twice and re-order the FROM and JOIN clauses to start with the main granular table, CourseScheduleAttendees, where other tables serve as lookups in a hub-spoke fashion:
SELECT cc.CourseName
,FORMAT(cs.StartDate, 'dd/MM/yyyy') AS 'Start Date'
,FORMAT(cs.EndDate, 'dd/MM/yyyy') AS 'End Date'
,a.AcademyName
,r.RoomName
,t.FirstName + ' ' + t.LastName AS 'Trainer'
,s.FirstName + ' ' + s.LastName AS 'Student'
FROM CourseScheduleAttendees csa
INNER JOIN CourseScheduleTrainers cst
ON csa.TrainerID = cst.TrainerID
INNER JOIN Employees t
ON cst.EmployeeID = t.EmployeeID
AND t.EmployeeType = 'T'
INNER JOIN Employees s
ON csa.AttendeeID = s.EmployeeID
AND s.EmployeeType = 'S'
INNER JOIN CourseCatalog cc
ON csa.CourseCatalogID = cc.CourseCatalogID
INNER JOIN CourseSchedule cs
ON cc.CourseScheduleID = cs.CourseScheduleID
INNER JOIN Rooms r
ON cs.RoomsID = r.RoomsID
INNER JOIN Academies a
ON r.AcademyID = a.AcademyID;

using joins together with aggregates, and retrieving rows when no aggregate exists

The following query on my MySQL tables returns rows from the purchaseorder table that have corresponding entries in the deliveryorder table. How do I construct this query so that I get rows from the purchaseorder table even if no corresponding rows exist in the deliveryorder table? If the users want to see sql table CREATE statements, I can post those, but I'm not posting now as it really makes the question too big.
SELECT
`purchaseorder`.`id` AS `po_id`,
`purchaseorder`.`order_quantity` AS `po_order_quantity`,
`purchaseorder`.`applicable_approved_unit_rate` AS `po_unit_rate`,
`purchaseorder`.`applicable_sales_tax_rate` AS `po_tax_rate`,
`purchaseorder`.`order_date` AS `po_order_date`,
`purchaseorder`.`remarks` AS `po_remarks`,
`purchaseorder`.`is_open` AS `po_is_open`,
`purchaseorder`.`is_active` AS `po_is_active`,
`purchaseorder`.`approved_rate_id` AS `po_app_rate_id`,
`supplier`.`name` AS `sup_name`,
SUM(`deliveryorder`.`quantity`) AS `total_ordered`
FROM `purchaseorder`
LEFT JOIN `deliveryorder` ON (`deliveryorder`.`purchase_order_id` = `purchaseorder`.`id`)
INNER JOIN `approvedrate` ON (`purchaseorder`.`approved_rate_id` = `approvedrate`.`id`)
INNER JOIN `supplier` ON (`approvedrate`.`supplier_id` = `supplier`.`id`)
WHERE (
`purchaseorder`.`is_active` = 1
AND `purchaseorder`.`is_open` = 1
AND `deliveryorder`.`is_active` = 1
AND `approvedrate`.`material_id` = 2
)
HAVING `purchaseorder`.`order_quantity` >= `total_ordered` + 1
You have an aggregating function but no GROUP BY clause, which is wierd, but anyway - something like this? Oops - edited...
SELECT po.id po_id
, po.order_quantity po_order_quantity
, po.applicable_approved_unit_rate po_unit_rate
, po.applicable_sales_tax_rate po_tax_rate
, po.order_date po_order_date
, po.remarks po_remarks
, po.is_open po_is_open
, po.is_active po_is_active
, po.approved_rate_id po_app_rate_id
, s.name sup_name
, SUM(do.quantity) total_ordered
FROM purchaseorder po
LEFT
JOIN deliveryorder do
ON do.purchase_order_id = po.
AND do.is_active = 1
LEFT
JOIN approvedrate ar
ON ar.id = po.approved_rate_id
AND ar.material_id = 2
LEFT
JOIN supplier s
ON s.id = ar.supplier_id
WHERE po.is_active = 1
AND po.is_open = 1
HAVING po.order_quantity >= total_ordered + 1
I couldn't work out how to get the desired results all in one query, but ended up using the following two queries to fulfill my requirements: -
1st query
SELECT
pot.`id` AS `po_id`,
pot.`order_quantity` AS `po_order_quantity`,
pot.`applicable_approved_unit_rate` AS `po_unit_rate`,
pot.`applicable_sales_tax_rate` AS `po_tax_rate`,
pot.`is_open` AS `po_is_open`,
pot.`is_active` AS `po_is_active`,
st.`id` AS `sup_id`,
st.`name` AS `sup_name`,
SUM(dot.`quantity`) AS `total_ordered`
FROM `purchaseorder` pot
INNER JOIN `deliveryorder` dot ON (dot.`purchase_order_id` = pot.`id`)
INNER JOIN `approvedrate` art ON (pot.`approved_rate_id` = art.`id`)
INNER JOIN `supplier` st ON (art.`supplier_id` = st.`id`)
WHERE (
pot.`is_active` = 1
AND pot.`is_open` = 1
AND art.`material_id` = #materialid
AND art.`in_effect` = 1
AND art.`is_active` = 1
AND dot.`is_active` = 1
AND st.`is_active` = 1
)
HAVING pot.`order_quantity` >= `total_ordered` + #materialquantity
2nd query
SELECT
pot.`id` AS `po_id`,
pot.`order_quantity` AS `po_order_quantity`,
pot.`applicable_approved_unit_rate` AS `po_unit_rate`,
pot.`applicable_sales_tax_rate` AS `po_tax_rate`,
pot.`is_open` AS `po_is_open`,
pot.`is_active` AS `po_is_active`,
st.`id` AS `sup_id`,
st.`name` AS `sup_name`,
0 AS `total_ordered`
FROM `purchaseorder` pot
INNER JOIN `approvedrate` art ON (pot.`approved_rate_id` = art.`id`)
INNER JOIN `supplier` st ON (art.`supplier_id` = st.`id`)
WHERE (
pot.`is_active` = 1
AND pot.`is_open` = 1
AND art.`material_id` = #materialid
AND art.`in_effect` = 1
AND art.`is_active` = 1
AND st.`is_active` = 1
AND pot.`order_quantity` >= #materialquantity
AND pot.`id` NOT IN
(
SELECT dot.`purchase_order_id`
FROM `deliveryorder` dot
WHERE dot.is_active = 1
)
)

MySQL Update table with sum value of another table

I have a query that I can't seem to manipulate to work in a SUM function in MySQL:
Here is what I want:
UPDATE account_seeds AS a
INNER JOIN b AS b ON b.accountID = a.accountID AND a.areaID = b.areaID
INNER JOIN b_seed AS s ON s.buildingID = b.buildingID
INNER JOIN seed_class AS c ON c.seedID = s.seedID
SET a.amount = a.amount + SUM(s.amount)
WHERE b.status='active' AND a.seedID = s.seedID
Now it obviously won't let me use the SUM in the update without separating it. I have tried joining select queries but can't quite get my head around it. The basic premise being that I have multiple buildings(rows) that has a seed value that will increase total seeds of that type in the area for a particular account. Without the sum it only updates one of the buildings that has a matching seed value
UPDATE
account_seeds AS a
INNER JOIN
( SELECT b.accountID, b.areaID, s.seedID
, SUM(s.amount) AS add_on
FROM b AS b
INNER JOIN b_seed AS s
ON s.buildingID = b.buildingID
INNER JOIN seed_class AS c
ON c.seedID = s.seedID
WHERE b.status = 'active'
GROUP BY b.accountID, b.areaID, s.seedID
) AS g
ON g.accountID = a.accountID
AND g.areaID = a.areaID
AND g.seedID = a.seedID
SET
a.amount = a.amount + g.add_on ;
Maybe you can use a nested query:
UPDATE account_seeds AS a
INNER JOIN b AS b ON b.accountID = a.accountID AND a.areaID = b.areaID
INNER JOIN b_seed AS s ON s.buildingID = b.buildingID
INNER JOIN seed_class AS c ON c.seedID = s.seedID
SET a.amount = a.amount + (SELECT SUM(amount) FROM b_seed)
WHERE b.status='active' AND a.seedID = s.seedID
Can you try that?

MYSQL Query - Some results don't return

I have a problem im my sql query:
SELECT table_2.id, SUM(table_2.time + table_4.time + table_6.time + table_8.time + table_10.time + table_12.time) AS total_time, SUM(table_2.connects + table_4.connects + table_6.connects + table_8.connects + table_10.connects + table_12.connects) AS total_connects FROM table_2
INNER JOIN table_4 ON table_2.id = table_4.id
INNER JOIN table_6 ON table_2.id = table_6.id
INNER JOIN table_8 ON table_2.id = table_8.id
INNER JOIN table_10 ON table_2.id = table_10.id
INNER JOIN table_12 ON table_2.id = table_12.id
GROUP BY table_2.authid ORDER BY total_time DESC
Ok, I have a script that grabs the user IDS and the time they spent and then puts it in mysql tables depending on which forum they have entered. The query above seems to be working fine but only for the users that have entered all forums, because the others that haven't entered in all forums don't return any result.
The ID is always the same, it is the users ID and connects is the number of times the user enters the specific forum.
If you understand my problem and know the answear please let me know, otherwise I'll try to explain better
Thanks
I think a good way to do this may be:
SELECT id, SUM(time), SUM(connects)
FROM (
SELECT id, time, connects FROM table_2
UNION ALL
SELECT id, time, connects FROM table_4
UNION ALL
SELECT id, time, connects FROM table_6
UNION ALL
SELECT id, time, connects FROM table_8
UNION ALL
SELECT id, time, connects FROM table_10
UNION ALL
SELECT id, time, connects FROM table_12
) uniontable
GROUP BY id
Since they all have the same fields.
EDIT: And it sounds like it may not be such a strange idea to merge them into one table, especially if you want to count the total time like this ;)
EDIT 2: I'm sorry, that wasn't valid SQL at all. This should be better.
Replace the INNER JOIN by a LEFT OUTER JOIN this will get you results over all the tables. You might need to re-define the SUM probably you'll get NULL on users who haven't visited all forums...
Replace the JOIN with the LEFT JOIN:
SELECT people.id, SUM(COALESCE(table_2.time, 0) + COALESCE(table_4.time, 0) + table_6.time, 0) + COALESCE(table_8.time, 0) + COALESCE(table_10.time, 0) + COALESCE(table_12.time, 0)) AS total_time,
SUM(COALESCE(table_2.connects, 0) + COALESCE(table_4.connects, 0) + COALESCE(table_6.connects, 0) + COALESCE(table_8.connects, 0) + COALESCE(table_10.connects, 0) + COALESCE(table_12.connects, 0)) AS total_connects
FROM people p
LEFT JOIN
table_2
ON table_2.id = people.id
LEFT JOIN
table_4
ON people.id = table_4.id
LEFT JOIN
table_6
ON people.id = table_6.id
LEFT JOIN
table_8
ON people.id = table_8.id
LEFT JOIN
table_10
ON people.id = table_10.id
LEFT JOIN
table_12
ON people.id = table_12.id
GROUP BY
people.authid
ORDER BY
total_time DESC
#afonso: I think you should populate all those time tables whenever a new user is created by inserting the user with a time of 0 (just so that they're in the table). Would this be an acceptable compromise for your application just to have those users in the tables so your initial query will work?
You will need to use outer joins and you will need to use IFNULL or something similar to map the "user wasn't in forum" nulls to zeroes.
SELECT t2.id,
SUM(IFNULL(t2.time, 0) + IFNULL(t4.time, 0) +
IFNULL(t6.time, 0) + IFNULL(t8.time, 0) +
IFNULL(t10.time, 0) + IFNULL(t12.time, 0)) AS total_time,
SUM(IFNULL(t2.connects, 0) + IFNULL(t4.connects, 0) +
IFNULL(t6.connects, 0) + IFNULL(t8.connects, 0) +
IFNULL(t10.connects, 0) + IFNULL(t12.connects, 0)) AS total_connects
FROM table_2 AS t2
LEFT JOIN table_4 AS t4 ON t2.id = t4.id
LEFT JOIN table_6 AS 76 ON t2.id = t6.id
LEFT JOIN table_8 AS t8 ON t2.id = t8.id
LEFT JOIN table_10 AS t10 ON t2.id = t10.id
LEFT JOIN table_12 AS t12 ON t2.id = t12.id
GROUP BY t2.id ORDER BY total_time DESC
This almost works; it does work for all users that visit the forum for which the information is stored in table_2. To make it work for people who don't visit the 'table_2 forum', the query needs to use the table that defines users and do the outer joins with that table:
SELECT u.id,
SUM(IFNULL(t2.time, 0) + IFNULL(t4.time, 0) +
IFNULL(t6.time, 0) + IFNULL(t8.time, 0) +
IFNULL(t10.time, 0) + IFNULL(t12.time, 0)) AS total_time,
SUM(IFNULL(t2.connects, 0) + IFNULL(t4.connects, 0) +
IFNULL(t6.connects, 0) + IFNULL(t8.connects, 0) +
IFNULL(t10.connects, 0) + IFNULL(t12.connects, 0)) AS total_connects
FROM Users AS u
LEFT JOIN table_2 AS t2 ON u.id = t2.id
LEFT JOIN table_4 AS t4 ON u.id = t4.id
LEFT JOIN table_6 AS 76 ON u.id = t6.id
LEFT JOIN table_8 AS t8 ON u.id = t8.id
LEFT JOIN table_10 AS t10 ON u.id = t10.id
LEFT JOIN table_12 AS t12 ON u.id = t12.id
GROUP BY u.id ORDER BY total_time DESC
However, given the symmetry of the table_N tables, I think you should do as Spiny Norman
suggests and redesign your schema so that there is one table that stores the timing and connection values:
CREATE TABLE ForumUsage
(
ForumID INTEGER NOT NULL REFERENCES Forums,
UserID INTEGER NOT NULL REFERENCES Users,
Time INTEGER NOT NULL,
Connects INTEGER NOT NULL
);
Then you sum over the entries in that table.