We have a SQL query that produces a report. We have sucussfully joined our settings table to update the integer values with the correct items, We have also used a union to display our three types of users.
We would like to take this query and order it by the e_job.objId field, however we are finding it really difficult with the multiple joins and unions.
If anyone could help it would be appreciated.
SELECT e_job.objId AS 'Job Number', e_student.Lastname AS 'Last Name', e_student.Name AS 'First Name', e_asset.objId AS 'Asset Number', e_asset.aSerialNumber AS 'Serial Number', si.sLabel AS 'Issue', srt.sLabel AS 'Repair Type', ss.sLabel As 'Status', e_job.note 'Description',FROM_UNIXTIME(e_job.jCreatedAt,'%d/%m/%y') AS 'Date Created'
FROM e_job
INNER JOIN e_student ON e_job.jName = e_student.username
INNER JOIN e_asset ON e_job.jAsset = e_asset.aId
LEFT JOIN e_settings si ON si.sKey = 'job_issue' AND si.sValue = e_job.jIssue
LEFT JOIN e_settings srt ON srt.sKey = 'job_rep_type' AND srt.sValue = e_job.jRepairType
LEFT JOIN e_settings ss ON ss.sKey = 'job_status' AND ss.sValue = e_job.jStatus
WHERE jStatus = 1 && jRepairType = 2
UNION
SELECT e_job.objId AS 'Job Number', e_teachers.Lastname AS 'Last Name', e_teachers.Name AS 'First Name', e_asset.objId AS 'Asset Number', e_asset.aSerialNumber AS 'Serial Number', si.sLabel AS 'Issue', srt.sLabel AS 'Repair Type', ss.sLabel As 'Status', e_job.note 'Description',FROM_UNIXTIME(e_job.jCreatedAt,'%d/%m/%y') AS 'Date Created'
FROM e_job
INNER JOIN e_teachers ON e_job.jName = e_teachers.username
INNER JOIN e_asset ON e_job.jAsset = e_asset.aId
LEFT JOIN e_settings si ON si.sKey = 'job_issue' AND si.sValue = e_job.jIssue
LEFT JOIN e_settings srt ON srt.sKey = 'job_rep_type' AND srt.sValue = e_job.jRepairType
LEFT JOIN e_settings ss ON ss.sKey = 'job_status' AND ss.sValue = e_job.jStatus
WHERE jStatus = 1 && jRepairType = 2
UNION
SELECT e_job.objId AS 'Job Number', e_supportStaff.Lastname AS 'Last Name', e_supportStaff.Name AS 'First Name', e_asset.objId AS 'Asset Number', e_asset.aSerialNumber AS 'Serial Number', si.sLabel AS 'Issue', srt.sLabel AS 'Repair Type', ss.sLabel As 'Status', e_job.note 'Description',FROM_UNIXTIME(e_job.jCreatedAt,'%d/%m/%y') AS 'Date Created'
FROM e_job
INNER JOIN e_supportStaff ON e_job.jName = e_supportStaff.username
INNER JOIN e_asset ON e_job.jAsset = e_asset.aId
LEFT JOIN e_settings si ON si.sKey = 'job_issue' AND si.sValue = e_job.jIssue
LEFT JOIN e_settings srt ON srt.sKey = 'job_rep_type' AND srt.sValue = e_job.jRepairType
LEFT JOIN e_settings ss ON ss.sKey = 'job_status' AND ss.sValue = e_job.jStatus
WHERE jStatus = 1 && jRepairType = 2
Thank you
If you add an ORDER BY clause to the end of the query it should apply to the entire result set. You can try adding this:
ORDER BY `Job Number`
Also, you don't need to specify aliases in union queries other than the first one. The first set of aliases are what stick.
Related
I'm looking for a more efficient way to write this query which displays meta values for an order in a single row. I can't think of a solution myself but before I redesign the database I wanted to see if anyone has any ideas to avoid 11 INNER JOINs. Here is my query which currently takes 20 seconds to load a single result (which is obviously not practical):
SELECT
o1.order_id,
o1.order_status AS 'Order Status',
m3.meta_value AS 'UOP Order Status',
m4.meta_value AS 'UOP Registration Date',
m5.meta_value AS 'UOP Banner Registration',
m6.meta_value AS 'UOP Banner Date',
m7.meta_value AS 'Course Completion Date',
m8.meta_value AS 'Course Grade',
m9.meta_value AS 'Grade Submission Date',
m1.meta_value AS 'First Name',
m2.meta_value AS 'Last Name',
o1.order_date AS 'Order Date',
m10.meta_value,
m11.meta_value,
o1.partner_id AS 'Source'
FROM partner_orders o1
INNER JOIN partner_order_meta m1
ON (o1.order_id = m1.order_id)
INNER JOIN partner_order_meta m2
ON (o1.order_id = m2.order_id)
INNER JOIN partner_order_meta m3
ON (o1.order_id = m3.order_id)
INNER JOIN partner_order_meta m4
ON (o1.order_id = m4.order_id)
INNER JOIN partner_order_meta m5
ON (o1.order_id = m5.order_id)
INNER JOIN partner_order_meta m6
ON (o1.order_id = m6.order_id)
INNER JOIN partner_order_meta m7
ON (o1.order_id = m7.order_id)
INNER JOIN partner_order_meta m8
ON (o1.order_id = m8.order_id)
INNER JOIN partner_order_meta m9
ON (o1.order_id = m9.order_id)
INNER JOIN partner_order_meta m10
ON (o1.order_id = m10.order_id)
INNER JOIN partner_order_meta m11
ON (o1.order_id = m11.order_id)
WHERE m1.meta_key = 'First Name' AND m2.meta_key = 'Last Name' AND m3.meta_key = 'uop_order_status' AND m4.meta_key = 'uop_registration_date' AND m5.meta_key = 'uop_banner_registration' AND m6.meta_key = 'uop_banner_registration_date' AND m7.meta_key = 'course_completion_date' AND m8.meta_key = 'course_grade' AND m9.meta_key = 'grade_submission_date' AND m10.meta_key = 'Course Number' AND m11.meta_key = 'Course Title';
Use grouping:
SELECT
o1.order_id,
o1.order_status AS `Order Status`,
MAX(IF(m.meta_key = 'First Name', m.meta_value, NULL)) AS `First Name`,
MAX(IF(m.meta_key = 'Last Name', m.meta_value, NULL)) AS `Last Name`,
...
FROM partner_orders AS o1
JOIN partner_order_meta AS m ON o1.order_id = m.order_id
GROUP BY o1.order_id
Novice would greatly appreciate assistance on the following 3706 error message:
expected something between the word 'Calls' and the 'case' keyword
SELECT distinct
b.emp_nbr,
b.prim_terr_desc,
a.sales_terr_nbr,
TRIM (B.first_nm) ||' '|| TRIM (B.last_nm) as AE_Name,
count (distinct call_nbr) as Calls
case (when a.sale_call_chanl_desc LIKE 'Face to Face%' then 'F2F'
when a.sale_call_chanl_desc = 'Telephone' then 'Phone'
when a.sale_call_chanl_desc LIKE 'Web Meeting%' then 'Web_Meeting'
end) as Channel
FROM isell_prod_view_db.sfdc_call_action a
LEFT OUTER JOIN isell_prod_view_db.sfdc_customer_info c ON (a.cust_acct_nbr = c.cust_acct_nbr and a.rec_delt_flg = 'N')
LEFT OUTER JOIN isell_prod_view_db.sfdc_opportunity d ON (d.cust_acct_nbr = c.cust_acct_nbr and d.delt_flg = 'N')
LEFT OUTER JOIN isell_prod_view_db.sfdc_user_profile b ON a.crte_by_user_key_nbr = b.user_key_nbr
LEFT OUTER JOIN isell_prod_view_db.sfdc_opportunity_item e ON (e.oprty_key_nbr = d.oprty_key_nbr and e.delt_flg = 'N')
where a.sale_call_stat_desc = 'Completed'
and a.sales_div_nbr = '8'
and a.sales_grp_nbr = '9'
and a.sales_org_nbr ='30'
and b.prim_terr_desc LIKE ('8-9-30%')
and a.priv_entr_flg='N'
and a.sale_call_chanl_desc is not null
and CAST(a.call_dt AS date format 'MM/DD/YYYY') between '06/01/2019' and '05/31/2020'
group by 1,2,3,4
I rejigged the code. This works. I think i needed a comma after "AS Channel"
SELECT distinct
b.emp_nbr,
TRIM (B.first_nm) ||' '|| TRIM (B.last_nm) as AE_Name,
b.prim_terr_desc,
b.prim_terr_seg_nbr,
case when CAST(a.call_dt AS date format 'MM/DD/YYYY') between '12/01/2019' and '02/29/2020' then 'Q3'
when CAST(a.call_dt AS date format 'MM/DD/YYYY') between '03/01/2020' and '05/31/2020' then 'Q4'
end as Qtr,
count (distinct call_nbr) as Calls
FROM isell_prod_view_db.sfdc_call_action a
LEFT OUTER JOIN isell_prod_view_db.sfdc_customer_info c ON (a.cust_acct_nbr = c.cust_acct_nbr and a.rec_delt_flg = 'N')
LEFT OUTER JOIN isell_prod_view_db.sfdc_opportunity d ON (d.cust_acct_nbr = c.cust_acct_nbr and d.delt_flg = 'N')
LEFT OUTER JOIN isell_prod_view_db.sfdc_user_profile b ON a.crte_by_user_key_nbr = b.user_key_nbr
LEFT OUTER JOIN isell_prod_view_db.sfdc_opportunity_item e ON (e.oprty_key_nbr = d.oprty_key_nbr and e.delt_flg = 'N')
where a.sale_call_stat_desc = 'Completed'
and a.sales_div_nbr = '8'
and a.sales_grp_nbr = '9'
and a.sales_org_nbr ='30'
and b.prim_terr_desc LIKE ('8-9-30%')
and A.rec_delt_flg = 'N'
and A.child_event_flg='N'
and a.priv_entr_flg='N'
and B.prim_terr_seg_desc not in ('No Coverage')
and A.sale_call_chanl_desc in ('Telephone', 'Phone', 'Face to Face - Appt', 'Face to Face - No Appt', 'Web Meeting')
and B.prim_terr_seg_nbr not in ('3', '8', '25')
and CAST(a.call_dt AS date format 'MM/DD/YYYY') between '12/01/2019' and '05/31/2020'
group by 1,2,3,4,5
Please help me to optimize below Query -
SELECT DISTINCT
al.displayName AS 'Brand',
al.locationName AS 'Campus',
pg.groupName AS 'School Phase',
result.programName AS 'Grade',
pc.categoryName AS 'Grade Category',
result.batchName AS 'Intake',
result.periodName AS 'Period',
admission.id AS 'ADmission',
result.stdName AS 'Student Name',
usr.code AS 'Student Id',
result.courseName AS 'Subject',
result.courseVariant AS 'Subject Variant',
cc.categoryName AS 'Subject Category',
fac.printName AS 'Teacher',
result.planPrintName AS 'Scheme',
planRank.marksObtainedFrom AS 'Maximum Marks',
planRank.gradeObtainedFrom AS 'Maximum Grade',
planRank.obtainedMarks AS 'Subject Level Marks',
planRank.grade AS 'Subject Grade',
planRank.obtainedMarks AS 'Percentage',
planRank.status AS 'Result Status',
result.levelOnePrintName AS 'Type',
typeRank.effectiveMarks AS 'Type Marks',
typeRank.grade AS 'Type Grade',
typeRank.status AS 'Type Result Status',
result.levelTwoPrintName AS 'Sub Type',
subTypeRank.effectiveMarks AS 'Sub Type Marks',
subTypeRank.grade AS 'Sub Type Grade',
subTypeRank.status AS 'Sub Type Result Status',
result.levelThreePrintName AS 'Method',
result.effectiveMarks AS 'Method Marks',
result.grade AS 'Method Grade',
result.status AS 'Method Result Status',
CASE
WHEN evntDetail.eventName IS NULL THEN evnt.detailSequenceNumber
WHEN evntDetail.eventName IS NOT NULL THEN evntDetail.eventName
ELSE NULL
END AS 'Event',
eventMarks.effectiveMarks AS 'Event Marks',
eventMarks.finalGrade AS 'Event Grade'
FROM
marksheet AS result
INNER JOIN
admission AS admission ON admission.id = result.admissionId
INNER JOIN
users AS usr ON usr.id = result.studentId
INNER JOIN
academy_location AS al ON al.id = admission.academyLocationId
INNER JOIN
programs AS prgm ON prgm.id = result.programId
LEFT OUTER JOIN
program_group AS pg ON pg.id = prgm.programGroupId
LEFT OUTER JOIN
program_category AS pc ON pc.id = prgm.programCategoryId
LEFT OUTER JOIN
courses AS course ON course.id = result.courseId
LEFT OUTER JOIN
course_category AS cc ON cc.id = course.courseCategoryId
LEFT OUTER JOIN
program_batch_course_param AS param ON result.courseVariantId = param.courseVarientId
AND result.periodId = param.progBatchPeriodConfigId
LEFT OUTER JOIN
prog_batch_course_faculty AS pbcf ON pbcf.progBatchCourseParamId = param.id
LEFT OUTER JOIN
users AS fac ON fac.id = pbcf.facultyId
LEFT OUTER JOIN
evaluation_plan_rank AS planRank ON result.admissionId = planRank.admissionId
AND (result.courseVariantId = planRank.courseVariantId
OR planRank.courseVariantId IS NULL)
AND result.sectionId = planRank.sectionId
AND result.periodId = planRank.periodId
AND result.evaluationPlanId = planRank.evaluationPlanId
LEFT OUTER JOIN
evaluation_plan_level_one_rank AS typeRank ON result.admissionId = typeRank.admissionId
AND (result.courseVariantId = typeRank.courseVariantId
OR typeRank.courseVariantId IS NULL)
AND result.periodId = typeRank.periodId
AND result.sectionId = typeRank.sectionId
AND result.evaluationPlanLevelOneId = typeRank.evaluationPlanLevelOneId
LEFT OUTER JOIN
evaluation_plan_level_two_rank AS subTypeRank ON result.admissionId = subTypeRank.admissionId
AND (result.courseVariantId = subTypeRank.courseVariantId)
AND result.periodId = subTypeRank.periodId
AND result.sectionId = subTypeRank.sectionId
AND result.evaluationPlanLevelTwoId = subTypeRank.evaluationPlanLevelTwoId
INNER JOIN
eval_seq_detail AS evnt ON result.evaluationPlanThreeId = evnt.evalSequenceId
LEFT OUTER JOIN
examination_result AS eventMarks ON result.admissionId = eventMarks.admissionId
AND (result.courseVariantId = eventMarks.courseVariantId
OR eventMarks.courseVariantId IS NULL)
AND result.sectionId = eventMarks.sectionId
AND result.periodId = eventMarks.periodId
AND evnt.id = eventMarks.evaluationDetailSequenceId
LEFT OUTER JOIN
evaluation_type_course typeCourse ON eventMarks.courseVariantId = typeCourse.courseVariantId
AND eventMarks.periodId = typeCourse.periodId
LEFT OUTER JOIN
exam_event_detail evntDetail ON eventMarks.evaluationDetailSequenceId = evntDetail.eventId
AND evntDetail.evaluationTypeCourseId = typeCourse.id
WHERE
eventMarks.examResultStatus IS NOT NULL
AND result.evaluationPlanId IS NOT NULL
AND result.evaluationPlanLevelOneId IS NOT NULL
AND result.evaluationPlanLevelTwoId IS NOT NULL
AND result.evaluationPlanThreeId IS NOT NULL;
In tables marksheet = '740119' and examination_result = '4891575' approx records.
when I execute query then it will take around 10 min and also show time out error, as data-set is large.
I applied indexes on table's for performance but still Query take lots of time.
I applied Explain on Query to check status -
Add the keyword "STRAIGHT_JOIN" to you query. It looks like you have everything in proper logical alignment. You are querying from the main table and joining to all the lookup tables secondary. MySQL sometimes tries to optimize based on table row sizes and will look at a smaller table as a more beneficial path and can choke.
SELECT STRAIGHT_JOIN (rest of query)
Tells MySQL to do the query in the order you provided, don't think for me.
Now, that said, you don't really have a WHERE clause that may be taking advantage of an index. To prevent the need of having to go to every data page for the records, if you have an index on the where clauses, the engine can pre-qualify those records where not null via the index. Assuming that each evaluation plan is an integer (numeric) based "ID" value, I would add an index on
( evaluationPlanId, evaluationPlanLevelOneId, evaluationPlanLevelTwoId, evaluationPlanThreeId )
In the below query, I am trying to SELECT Destination_City.Name_, and to do so need to join Destination_City.Destination_City_ID with Contract_Items.Destination_City_ID, however the latter table is already inner joined with the Contract table.
SELECT
contract.Description,
---Destination_City.Name_,
contract_type.type AS 'Contract Type',
contract.Tour_Summary AS 'Tour Name',
employee.First_Name AS 'First Name',
employee.Last_name AS 'Last Name',
Currency_.Currency_Name AS 'Currency',
contract_Items.twin AS 'Twin Rate',
contract_items.Item_Rate AS 'Rate'
FROM
Contract
INNER JOIN Employee
ON Contract.Contracted_By_Employee_Id = Employee.Employee_Id
INNER JOIN Contract_Items
ON Contract.Contract_ID = Contract_Items.Contract_ID
INNER JOIN Currency_
ON Contract.Currency_Id = Currency_.Currency_Id
INNER JOIN Contract_Type
ON Contract.Contract_Type_Id = contract_type.Contract_Type_Id
Essentially Table 2 needs to be joined to Table 3, but Table 2 is already joined to Table 1. I have tried a couple of different approaches but both have thrown errors, and I am not sure how to write up this query.
It should be no problem to get your Name_ column with joining the DESTINATION_CITY table:
SELECT
contract.Description,
Destination_City.Name_,
contract_type.type AS 'Contract Type',
contract.Tour_Summary AS 'Tour Name',
employee.First_Name AS 'First Name',
employee.Last_name AS 'Last Name',
Currency_.Currency_Name AS 'Currency',
contract_Items.twin AS 'Twin Rate',
contract_items.Item_Rate AS 'Rate'
FROM
Contract
INNER JOIN Employee
ON Contract.Contracted_By_Employee_Id = Employee.Employee_Id
INNER JOIN Contract_Items
ON Contract.Contract_ID = Contract_Items.Contract_ID
INNER JOIN Currency_
ON Contract.Currency_Id = Currency_.Currency_Id
INNER JOIN Contract_Type
ON Contract.Contract_Type_Id = contract_type.Contract_Type_Id
INNER JOIN Destination_City
ON Destination_City.Destination_City_ID = Contract_Items.Destination_City_ID
Please note that the order of the join operations is irrelevant, if you have inner joins only. It's only required that one of the tables is already joined before.
this?
FROM Contract
INNER JOIN Employee
ON Contract.Contracted_By_Employee_Id = Employee.Employee_Id
INNER JOIN Contract_Items
ON Contract.Contract_ID = Contract_Items.Contract_ID
INNER JOIN Destination_City ON
Destination_City.Destination_City_ID = Contract_Items.Destination_City_ID
INNER JOIN Currency_
ON Contract.Currency_Id = Currency_.Currency_Id
INNER JOIN Contract_Type
ON Contract.Contract_Type_Id = contract_type.Contract_Type_Id
I have an existing query:
select ProductLinesID, ProductID, ProductName, ProductCatalog, ManufacturerName,
productMSDSStatus, productStatusDesc, productStatusIcon, DATE_FORMAT(dateAdded,'%d/%m/%Y') As dateAdded, DATE_FORMAT(ProductRevision,'%d/%m/%Y') as ProductRevision,
ManufacturerID, SupplierName, ProductID, DATE_FORMAT(dateLatestCheck, '%d/%m/%Y') as dateLatestCheck,s.SupplierID
from sds_productlines pl
right join sds_products p on p.ProductID = pl.productlinesProductID
left join sds_manufacturer m on p.ProductManufacturer = m.ManufacturerID
left join sds_product_status ps on p.productMSDSStatus = ps.productStatusID
left join sds_departments d on pl.ProductLinesDepartmentID = d.DepartmentID
left join sds_hospitals h on h.hospitalID = d.DepartmentHospitalID
left join sds_supplier s on s.SupplierID = pl.SupplierID
which is defined in a php page. I've been asked to add another parameter which is stored in another table, the problem is, on sds_product can have many "communications" which is basicly like a comment with a date_created. For example, if I wanted a list of communications for a given product, I would do:
select * from sds_product_comms as pc
join sds_comms c on pc.comms_id = c.comms_id
where prod_id = 2546
I wanted to do this directly in SQL, so is it possible to somehow make a sub query to stick these two together, without creating duplicate rows in the initial query.
For example I don't want 5 rows of the same product with the same max date_created.
desc sds_comms
'comms_id', 'int(10) unsigned', 'NO', 'PRI', '', 'auto_increment'
'method', 'int(10) unsigned', 'NO', '', '', ''
'dialogue', 'varchar(200)', 'NO', '', '', ''
'reply_id', 'int(10) unsigned', 'NO', '', '', ''
'comm_to', 'varchar(60)', 'NO', '', '', ''
'comm_from', 'varchar(60)', 'NO', '', '', ''
'man_id', 'int(10) unsigned', 'NO', '', '', ''
'supp_id', 'int(10) unsigned', 'NO', '', '', ''
'user_id', 'int(10) unsigned', 'NO', '', '', ''
'date_created', 'timestamp', 'NO', '', 'CURRENT_TIMESTAMP', ''
Sorry for the detail but its hard to get my head around it!
EDIT:
select ProductLinesID, ProductID, ProductName, ProductCatalog, ManufacturerName,
productMSDSStatus, productStatusDesc, productStatusIcon, DATE_FORMAT(dateAdded,'%d/%m/%Y') As dateAdded, DATE_FORMAT(ProductRevision,'%d/%m/%Y') as ProductRevision,
ManufacturerID, SupplierName, ProductID, DATE_FORMAT(dateLatestCheck, '%d/%m/%Y') as dateLatestCheck,s.SupplierID
,lastContact
from sds_productlines pl
right join sds_products p on p.ProductID = pl.productlinesProductID
left join sds_manufacturer m on p.ProductManufacturer = m.ManufacturerID
left join sds_product_status ps on p.productMSDSStatus = ps.productStatusID
left join sds_departments d on pl.ProductLinesDepartmentID = d.DepartmentID
left join sds_hospitals h on h.hospitalID = d.DepartmentHospitalID
left join sds_supplier s on s.SupplierID = pl.SupplierID
left join sds_product_comms pc on pc.prod_id = p.productID
left join (select comms_id, max(date_created) as lastContact from sds_comms group by comms_id ) as c2 on pc.comms_id = c2.comms_id
where productID=555;
would this be a correct way of doing it? With this method I'm getting different lastContact dates for the same productID :(
Try this:
select ProductLinesID, ProductID, ProductName, ProductCatalog, ManufacturerName,
productMSDSStatus, productStatusDesc, productStatusIcon, DATE_FORMAT(dateAdded,'%d/%m/%Y') As dateAdded, DATE_FORMAT(ProductRevision,'%d/%m/%Y') as ProductRevision,
ManufacturerID, SupplierName, ProductID, DATE_FORMAT(dateLatestCheck, '%d/%m/%Y') as dateLatestCheck,s.SupplierID,
c.date_created as lastContact
from sds_productlines pl
right join sds_products p on p.ProductID = pl.productlinesProductID
left join sds_manufacturer m on p.ProductManufacturer = m.ManufacturerID
left join sds_product_status ps on p.productMSDSStatus = ps.productStatusID
left join sds_departments d on pl.ProductLinesDepartmentID = d.DepartmentID
left join sds_hospitals h on h.hospitalID = d.DepartmentHospitalID
left join sds_supplier s on s.SupplierID = pl.SupplierID
left join sds_product_comms pc on pc.prod_id = p.productID
left join comms_id c on c.comms_id = pc.comms_id and c.date_created = (select max(date_created) from comms_id c2 where c2.comms_id = pc.comms_id)
where productID=555;
If I understand you correctly, you want a parameter that is in a table that is on the N end of a 1:N relationship and you want to have only 1 of each.
You can try grouping your data using GROUP BY.
Something like:
SELECT sds_product_comms.*, MAX(sds_comms.created_at) FROM sds_product_comms AS pc
JOIN sds_comms c ON pc.comms_id = c.comms_id
GROUP BY sds_product_comms.prod_id