adding two subqueries to produce third column - mysql

i need to add two values from two subqueries and add it to third column.
i can write whole subqueries twice to produce sum, but is there better way to do it?
SELECT
d.id,
CONCAT(d.disease, '( ', d.disease_nepali, ' ) ') AS DISEASE,
IFNULL((SELECT
patients.D_O_M + patients.D_O_F
FROM
patients
WHERE
clinic = 22
AND patients.disease = p.disease),
0) AS 'district1',
IFNULL((SELECT
patients.D_O_M + patients.D_O_F
FROM
patients
WHERE
clinic = 21 AND disease = p.disease),
0) AS 'district2'
FROM
diseases d
LEFT JOIN
patients p ON (d.id = p.disease AND p.district = 9
AND p.status = 1
AND p.report_date LIKE '2014-03%')
GROUP BY disease

You can use a sub select
SELECT t.*,t.district1 + t.district2 `new_col`
FROM (
SELECT d.id, CONCAT(d.disease, '( ' ,d.disease_nepali, ' ) ') AS DISEASE,
IFNULL((SELECT patients.D_O_M+patients.D_O_F FROM patients WHERE clinic = 22 AND patients.disease = p.disease),0) AS `district1` ,
IFNULL((SELECT patients.D_O_M+patients.D_O_F FROM patients WHERE clinic = 21 AND disease = p.disease),0) AS `district2`
FROM diseases d
LEFT JOIN patients p ON
(d.id = p.disease AND p.district = 9 AND p.status = 1 AND p.report_date LIKE '2014-03%')
GROUP BY disease
) t

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 mySQL to create a booking summary - joining multiple tables , calculating multiple fields

I am trying to create a table the shows a booking summary for a rafting business. The EER diagram shows how everything is related. I am struggling with how to show only 1 row per trip (i am returning multiple rows and the numbers are multiplied). Here is my code so far.
use www;
SELECT
d.destination_name,
tt.trip_type_name,
t.trip_number,
t.trip_date,
(e.first_name + e.last_name) AS guide_name,
t.trip_capacity,
COUNT(r.guest_id) AS guests_booked,
(COUNT(r.guest_id)-t.trip_capacity) AS positions_available
FROM
employees e,
destination d,
trip_type tt,
trips t,
reservation r
GROUP BY d.destination_name , tt.trip_type_name , t.trip_number , t.trip_date , guide_name , t.trip_capacity
ORDER BY d.destination_name , tt.trip_type_name , t.trip_date , t.trip_number;
OK so I have figured out the JOINs I am now struggling with concatenating the GUIDE NAME, it shows up as the number 0(zero). I have the same issue with another table that needs to show the guest name from a concatenated first and last name that corresponds to an id and trip number.
here is my code:
use www;
SELECT
d.destination_name,
tt.trip_type_name,
t.trip_number,
t.trip_date,
t.trip_capacity,
CONCAT(e.nick_name+' '+e.last_name AS guide_name
COUNT(r.guest_id) AS guests_booked,
(t.trip_capacity - COUNT(r.guest_id)) AS positions_available
FROM
trip_type tt
JOIN
trips t ON tt.trip_type_code = t.trip_type_code
JOIN
destination d ON t.destination_code = d.destination_code
JOIN
reservation r ON t.trip_number = r.trip_number
GROUP BY trip_number;
Second SQL query
use www;
SELECT
d.destination_name,
tt.trip_type_name,
t.trip_number,
t.trip_date,
CONCAT(e.last_name + ', ' + e.first_name) AS guide_name,
CONCAT(g.last_name + ', ' + g.first_name) AS guest_name,
ex.exp_name AS guest_experience,
g.age AS guest_age,
g.weight AS guest_weight,
g.swimmer AS guest_is_swimmer,
g.mobile_phone AS guest_mobile_phone
FROM
trip_type tt
JOIN
trips t ON tt.trip_type_code = t.trip_type_code
JOIN
destination d ON t.destination_code = d.destination_code
JOIN
reservation r ON t.trip_number = r.trip_number
JOIN
guests g ON r.guest_id = g.guest_id
JOIN
experience ex ON ex.exp_code = g.exp_code
JOIN
employees e ON t.guide_employee_id = e.employee_id
ORDER BY d.destination_name , tt.trip_type_name , t.trip_date , g.last_name , e.employee_id
You need condition on relation otherwise you obtain a cartesian product between the tables .
SELECT
d.destination_name,
tt.trip_type_name,
t.trip_number,
t.trip_date,
(e.first_name + e.last_name) AS guide_name,
t.trip_capacity,
COUNT(r.guest_id) AS guests_booked,
(COUNT(r.guest_id)-t.trip_capacity) AS positions_available
FROM trips t
inner join employees e on e.employee_id = t.employee_employee_id
inner join destination d on d.destination_code = t.destination_code
inner join trip_type tt on tt.trip_type_cde = t.trip_type_cde
inner join reservation r on r.trip_number = t.reservation_trip_number
GROUP BY d.destination_name , tt.trip_type_name , t.trip_number , t.trip_date , guide_name , t.trip_capacity
ORDER BY d.destination_name , tt.trip_type_name , t.trip_date , t.trip_number;

mysql joining two table without in common

i have this script.. first i run query 1 and store into array then query 2,
using a foreach, i combine them and create a list of urls..but this takes time.. is there a way i can do this just in mysql by combining the table even do they have no common column?
query 1
SELECT
c.id,
c.city_name,
r.region_name,
cr.country_name
FROM city AS c, region AS r, country AS cr
WHERE r.id = c.id_region
AND cr.id = c.id_country
AND cr.id IN
(SELECT id FROM country WHERE used = 1)
query 2
SELECT id, title FROM param WHERE active = 1
loop
foreach ($arrayCity as $city) {
foreach ($arrayParam as $param ) {
$paramTitle = str_replace(' ', '+', $param['title']);
$url = 'http://url/city/'. $city['id'] .'/paramId/'. $param['id'] .'/'.
$paramTitle .'/'. $city['region_name'] .'/'. $city['city_name'];
}
}
You don't have to join on a condition. Not doing so is called a CROSS JOIN. The CROSS keyword is optional. In fact, you are already doing this because , is a synonym.
FROM city AS c, region AS r, country AS cr, param
How about
Select 'http://url/city/' + c.id + '/paramId/' + p.id + '/' +
Replace(title, ' ', '+') + '/' + r.region_Name + '/' + c.city_Name
From city c
Join region r On r.id = c.id_region
Join country n On n.id = c.id_country
cross join param p
Where n.Uused = 1
And p.active = 1
Something like this. You can select a concatenated string with results from your base table.
SELECT
c.id,
c.city_name,
r.region_name,
cr.country_name,
('http://url/city/' + c.city_name + '/' + p.param + '/' + c.id) AS URL
FROM city AS c, region AS r, country AS cr
JOIN param p ON c.id = p.id
WHERE r.id = c.id_region AND cr.id = c.id_country AND cr.id IN (SELECT id FROM country WHERE used = 1)
My experience is in TSQL, but it'll be close in my SQL
Edit: Sorry, forgot the join

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
)
)