Can anyone help me to optimize this query ? I can probably add some indexes and get only date from the modified (CURRENT_TIMESTAMP) field ?
Thanks
Jeremy
SELECT a.providerName AS Assureur, b.insuranceType AS Produit, c.votedFor, c.votedFor2, c.email, c.comment, c.modified
FROM insuranceproviders AS a, insurancetypes AS b, insurancevotes AS c
WHERE a.id = c.providerId
AND b.id = c.insTypeId
following join query looks better:
SELECT a.providerName AS Assureur, b.insuranceType AS Produit,
c.votedFor, c.votedFor2, c.email, c.comment, c.modified
FROM insuranceproviders AS a
INNER JOIN insurancetypes AS b ON a.id = c.providerID
INNER JOIN insurancevotes AS c ON b.id = c.insTypeId
and You should add following INDEX:
ALTER TABLE insuranceproviders ADD INDEX(id);
ALTER TABLE insurancetypes ADD INDEX (providerID, insTypeId);
ALTER TABLE insurancevotes ADD INDEX(insTypeId);
You can try like below:
[Here I am doing Left join as i dont know the table structure instead you can also have inner join]
SELECT a.providerName AS Assureur, b.insuranceType AS Produit, c.votedFor, c.votedFor2, c.email, c.comment, c.modified
FROM insurancevotes AS c
LEFT JOIN insuranceproviders AS a ON a.id = c.providerId
LEFT JOIN insurancetypes AS b ON b.id = c.insTypeId
use indexes for a.id, c.providerId, b.id, c.id(if there is), c.insTypeId
Related
I try to improve this query but I do not made successefully. I use a some left join and subquerys (I don't know another form) We try to get all bookings from users with certain status and the number of bookings multiples related with this booking and get from the log user the origin. The query is slow even if use a limit clausure. I Appreciate all the help can you give me.
This is the query:
SELECT DISTINCT b.uneaque_id, b.id, b.status, b.route_status, b.username, b.purpose, b.transfer, b.pickup_date, b.pickup_time, b.return_time, b.amount, b.default_location, b.start_address_route_comments, b.start_address_route, b.end_address_route_comments, b.end_address_route, u1.first_name, u1.last_name, b.transaction_Id, b.manual_payment, mr.AddressCount, lu.origin
FROM bookingdetails b
LEFT JOIN log_users lu ON lu.uneaque_id = b.uneaque_id AND lu.command_type = 'NEW BOOKING'
LEFT JOIN (
SELECT booking_id, COUNT(*) AS AddressCount FROM booking_multiple_rides GROUP BY booking_id
) mr ON b.id = mr.booking_id,
userdetails u1 WHERE b.username = u1.email
AND u1.user_status IN ('Active', 'Blocked', 'Not_Active')
AND b.default_location = 1
PD: Sorry for my english.
You have a ON b.id = mr.booking_id, userdetails u1 WHERE
you should change with a proper inner join
SELECT DISTINCT b.uneaque_id
, b.id, b.status
, b.route_status
, b.username
, b.purpose
, b.transfer
, b.pickup_date
, b.pickup_time
, b.return_time
, b.amount
, b.default_location
, b.start_address_route_comments
, b.start_address_route
, b.end_address_route_comments
, b.end_address_route
, u1.first_name
, u1.last_name
, b.transaction_Id
, b.manual_payment
, mr.AddressCount
, lu.origin
FROM bookingdetails b
LEFT JOIN log_users lu ON lu.uneaque_id = b.uneaque_id AND lu.command_type = 'NEW BOOKING'
LEFT JOIN (
SELECT booking_id
, COUNT(*) AS AddressCount
FROM booking_multiple_rides GROUP BY booking_id
) mr ON b.id = mr.booking_id
INNER JOIN userdetails u1 ON b.username = u1.email
AND u1.user_status IN ('Active', 'Blocked', 'Not_Active')
AND b.default_location = 1
and be sure you have proper index on
table bookingdetails a composite index on columns ( uneaque_id , id, default_location)
table log_users a composite index on columns (uneaque_id, command_type)
table userdetails a cmposite index on columns (email,user_status )
Tip 1.
Hiding a derived table in a LEFT JOIN is a prescription for sluggishness.
Replace
mr.AddressCount
with
( SELECT COUNT(*)
FROM booking_multiple_rides
WHERE booking_id = b.id
GROUP BY booking_id ) AS AddressCount
and get rid of the LEFT JOIN ( SELECT ... ) AS mr ON ..
Tip 2 Use explicit JOINs, no the old-fashioned "comma-join":
JOiN userdetails u1
ON b.username = u1.email
This won't help performance but it will make things clearer.
Tip 3: If you need an INNER JOIN (u1) after a LEFT JOIN, use parentheses. Else, put the inner joins first, then the left joins. This makes it easier to use, but may screw up the logic.
Tip 4: Don't use LEFT unless you need it. When you dont need it, it confuses the reader (and the Optimizer). (Again, no performance change.)
Tip 5: Why are you using DISTINCT? That takes an extra pass over all the resultset.
If those do not help enough, then provide SHOW CREATE TABLE so we can critique the indexes.
I am having a problem with a query that sometimes, will have an empty field returned. I have tried to use CASE and COALESCE but I am likely constructing the query incorrectly.
What I need to do in the results is, if b.user_id returns empty, to copy the value from a.useracctid into b.user_id. I hope that makes sense???
Here is my query, no matter what I have tried it errors for me.
Thank you for any idea or hints you can provide
SELECT b.user_id,a.responsetime,a.latitude,a.longitude,
a.status,a.updatetime,c.address
FROM callouts_response a
LEFT JOIN ldap_user_accounts b on a.useracctid = b.id
LEFT JOIN callouts c on a.calloutid = c.id
WHERE calloutid = :cid
Not sure how you have used COALESCE() but you can do like
SELECT COALESCE(b.user_id,a.useracctid) as somecol,
a.responsetime,
a.latitude,
a.longitude,
a.status,
a.updatetime,
c.address
FROM callouts_response a
LEFT JOIN ldap_user_accounts b on a.useracctid = b.id
LEFT JOIN callouts c on a.calloutid = c.id
WHERE a.calloutid = :cid
Try this:
SELECT IF(b.user_id IS NULL, a.useracctid, b.user_id), a.responsetime,a.latitude,a.longitude,
a.status,a.updatetime,c.address
FROM callouts_response a
LEFT JOIN ldap_user_accounts b on a.useracctid = b.id
LEFT JOIN callouts c on a.calloutid = c.id
WHERE calloutid = :cid
I have 8 different tables and I would like to select only specific columns in one query. If I use this query I have wrong results :(
SELECT a.entity_id id
, a.field_imie_value imie
, c.field_nazwisko_value nazwisko
, d.field_preferencja_1_value preferencja1
, e.field_preferencja_2_value preferencja2
, f.field_preferencja_3_value preferencja3
, g.field_nr_niu_value nr_niu
, h.dystans odleglosc
, i.field_sytuacja_value sytuacja
FROM field_data_field_imie a
JOIN field_data_field_nazwisko c
, field_data_field_preferencja_1 d
, field_data_field_preferencja_2 e
, field_data_field_preferencja_3 f
, field_data_field_nr_niu g
, field_data_field_adres h
, field_data_field_sytuacja i
WHERE a.entity_id = b.entity_id
AND a.entity_id=c.entity_id
When you use joining tables you must use syntax similar to :
select A.field1 from table1 AS A inner join table2 as B on A.field1 = B.field1
syntax should be like this;
SELECT *
FROM field_data_field_imie a
JOIN field_data_field_nazwisko c on (a.entity_id=c.entity_id)
JOIN table x on (x.column=a.entitiy_id)
or you shouldn't use join at all.
actually number of tables is the important thing not how many fields you want however this is the syntax for joining more table :
elect A.field1 from table1 AS A inner join table2 as B on A.field1 = B.field1 inner join table3 AS C on table1.field1 = C.field1
and syntax for more joining is similar
Hello currently i have 4 tables in my database: which are tb_student, tb_history, tb_section and tb_adviser. so far i used this line to show me the history of a given student:
$qry_display = "SELECT
a.student_id, a.section_id, a.level, a.photo, a.address, a.father_occupation, a.father_phone, a.father_company, a.mother_occupation, a.mother_phone, a.mother_company,a.gpa,
b.fname, b.sex, b.lname, b.mname, b.birth_date, b.birth_place, b.address, b.father, b.father_degree, b.mother, b.mother_degree,
c.section_name, c.adviser_id
FROM tbl_er AS a
LEFT OUTER JOIN tbl_enroll AS b ON a.student_id = b.student_id
LEFT OUTER JOIN tbl_section AS c ON a.section_id = c.section_id
WHERE a.student_id=".$id." AND a.level='1st Year'";
my main problem is now i need to show the last name of the adviser with these other information. so i was thinking of putting. Note that tb_adviser is only CONNECTED to tb_section via adviser_id
LEFT OUTER JOIN tbl_adviser AS d ON a.student_id = c.adviser_id
I added this line before there where statement. and would insert this line in my SELECT fields.
d.lname_adviser
Currently it doesn't work. Anyone would shed some light into my problem.
Seeing the db structure would help, but it looks like you are trying to have JOIN on two columns that won't match. Is a.student_id going to match c.adviser_id?
Assuming the advisor_id is id in tbl_advisor then just add
LEFT OUTER JOIN tbl_advisor AS d
ON d.id = c.advisor_id
try this:
I think you should do
LEFT OUTER JOIN tbl_adviser AS d ON d.adviser_id = c.adviser_id
So your query would be:
Select .....
FROM tbl_er AS a
LEFT OUTER JOIN tbl_enroll AS b ON a.student_id = b.student_id
LEFT OUTER JOIN tbl_section AS c ON a.section_id = c.section_id
LEFT OUTER JOIN tbl_adviser AS d ON d.adviser_id = c.adviser_id
WHERE a.student_id=".$id." AND a.level='1st Year'
I'm doing a LEFT JOIN on three tables, where the table "time" doesn't necessarily contain any matching rows. But if no matching rows is found in that table, the linked data disappears.
SELECT
w.date AS worker_date,
w.name AS worker_name,
w.address AS worker_address,
w.zip AS worker_zip,
w.place AS worker_place,
w.phone AS worker_phone,
w.email AS worker_email,
w.company AS worker_company,
w.accessibility AS worker_accessibility,
c.date AS client_date,
c.name AS client_name,
c.address AS client_address,
c.zip AS client_zip,
c.place AS client_place,
c.phone AS client_phone,
c.email AS client_email,
c.web AS client_web,
c.contact AS client_contact,
j.date AS job_date,
j.client_id,
j.worker_id,
j.name AS job_name,
j.description AS job_description,
j.type AS job_type,
j.status AS job_status,
j.proof AS job_proof,
j.deadline AS job_deadline,
j.price AS job_price,
j.final_client AS job_final_client,
SUM(t.hours) AS time_hours
FROM
jobs AS j
LEFT JOIN (
workers AS w,
clients AS c,
time AS t
) ON (
w.id = j.worker_id AND
c.id = j.client_id AND
j.id = t.job_id
) GROUP BY
j.id;
How can I make this work?
Thank you in advance.
add
WHERE t.job_id IS NOT NULL before GROUP BY
Try Replace
SUM(t.hours) AS time_hours
to
(SELECT IFNULL(SUM(t.hours),0) FROM time WHERE time.job_id=j.job_id) AS time_hours
And remove the time from the join
I think your basic query is correct (with the join under braces)
Just replace
SUM(t.hours) AS time_hours
with
SUM(if(t.hours is NULL,0,t.hours)) AS time_hours
I am not sure if this is the problem here, but the behavior of commas vs JOINs changed after a certain MySQL version. Try this
...
FROM jobs AS j LEFT JOIN workers AS w ON w.id = j.worker_id
LEFT JOIN clients AS c c.id = j.client_id
LEFT JOIN `time` AS t ON j.id = t.job_id
...
Also modify the SUM with IFNULL as #ajreal suggests.