MySql error in your SQL syntax for date - mysql

I have just migrated my database from MS SQL to MySQL.
When running reports I now get the following error:
Application Execution Exception
Error Type: database : 0
Error Messages: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '2 YEAR(res_created) AS responseYear FROM Responses INNER JOIN ' at line 1
SQL Sent:
SELECT DISTINCT TOP #arguments.yearsToReturn# YEAR(res_created) AS responseYear
FROM
Responses
INNER JOIN
Questions ON Responses.question_id = Questions.question_id
INNER JOIN
Lookup_Survey_Questions ON Questions.question_id = Lookup_Survey_Questions.question_id
INNER JOIN
Survey ON Lookup_Survey_Questions.survey_id = Survey.survey_id
INNER JOIN
School ON Survey.sch_id = School.sch_id
INNER JOIN
Authority ON School.auth_id = Authority.auth_id
WHERE
Authority.auth_id = #arguments.authorityID#
AND
Questions.question_id = #arguments.questionID#
AND
Responses.survey_id IN (SELECT Survey.survey_id FROM Survey where Survey.sch_id in (SELECT School.sch_id FROM School where auth_id=#arguments.authorityID#))
ORDER BY
responseYear ASC
How can I resolve?
Thanks

I think that this can be simplified as follows...
SELECT DISTINCT YEAR(res_created) responseYear
FROM Responses r
JOIN Questions q
ON q.question_id = r.question_id
JOIN Lookup_Survey_Questions lsq
ON lsq.question_id = q.question_id
JOIN Survey u
ON u.survey_id = lsq.survey_id
JOIN School c
ON c.sch_id = u.sch_id
JOIN Authority a
ON a.auth_id = c.auth_id
WHERE a.auth_id = #arguments.authorityID#
AND q.question_id = #arguments.questionID#
AND c.auth_id=#arguments.authorityID#
ORDER
BY responseYear ASC
LIMIT 2;

"Top 2" isn't MySQL syntax. To select the first two results add limit 2 to the end of the query:
...
ORDER BY
responseYear ASC LIMIT 2

You are using the two clause at a place. You are using the DISTINCT and TOP that's why there is error.
Use this query:
SELECT DISTINCT YEAR(res_created) AS responseYear
FROM Responses
INNER JOIN Questions ON Responses.question_id = Questions.question_id
INNER JOIN Lookup_Survey_Questions ON Questions.question_id = Lookup_Survey_Questions.question_id
INNER JOIN Survey ON Lookup_Survey_Questions.survey_id = Survey.survey_id
INNER JOIN School ON Survey.sch_id = School.sch_id INNER JOIN Authority ON School.auth_id = Authority.auth_id
WHERE Authority.auth_id = 5 AND Questions.question_id = 20 AND Responses.survey_id IN (
SELECT Survey.survey_id FROM Survey where Survey.sch_id in (SELECT School.sch_id FROM School where auth_id=5))
ORDER BY responseYear ASC
LIMIT 0,2; //use the limit

Related

MYSQL Inner Join with IF Statement

I'm trying to join several tables in my database.
I need to get account information from the 'accounts' table with the latest meter history on it.
And if an account has no meter history, I want it to show 'meter' related fields as NULL.
Here's my query so far:
SELECT
accounts.id,
accounts.account_order,
acc.id AS accounts_class_id,
acc.zone,
acc.book,
acc.service_class,
acc.size,
acc.account_no AS series_no,
accounts.status,
application_address.address_line,
concessionaires.firstname,
concessionaires.middlename,
concessionaires.lastname,
mb.brand_name,
m.meter_no,
ms.meter_status
FROM
accounts
INNER JOIN
applications
ON accounts.application_id = applications.id
LEFT JOIN
application_address
ON applications.application_no = application_address.application_no
LEFT JOIN
concessionaires
ON applications.concessionaire_no = concessionaires.concessionaire_no
INNER JOIN
accounts_classifications acc
ON accounts.id = acc.account
INNER JOIN meter_history mh
ON mh.id = (SELECT id FROM meter_history mh2
WHERE mh2.account_id = accounts.id
ORDER BY mh2.status_date DESC
LIMIT 1)
LEFT JOIN
meter_status ms
ON mh.meter_status = ms.id
INNER JOIN
meter m
ON mh.meter = m.id
LEFT JOIN
meter_brand mb
ON m.meter_brand = mb.id
WHERE
acc.book = 1 AND acc.zone = 20 AND applications.status = '6' AND acc.status = '1'
This would return only accounts with meter history on it.
Where should I put my IF condition so I get accounts with no history as well, or if that is even possible with my query. Thank you!

UPDATE table by INNER JOIN and where clause

Got 2 tables as shown above. I want to update 'leaverecord.Consumed' from 'approved.Consumed' WHERE the leaverecord.name = approved.name and leaverecord.leavetype = approved.leavetype. Tried below query by getting error of 'Invalid use of group function
UPDATE leaverecord r INNER JOIN approved a
ON r.name = a.name
SET r.Consumed = SUM(DATEDIFF(a.todate,a.fromdate))
WHERE r.leavetype = a.leavetype AND
r.name = a.name
Calculate the consumed in a subquery and INNER JOIN it with leaverecord and then do the UPDATE like below. No WHERE clause needed.
Try this:
update leaverecord r
inner join (
select name, leavetype, sum(datediff(todate,fromdate)) consumed
from approved
group by name, leavetype
) a on r.name = a.name
and r.leavetype = a.leavetype
set r.consumed = a.consumed;

Merging code from two SQL queries

I am attempting to combine the contents of two separate (but very closely related) sql queries, but am finding it difficult to get something that doesn't return syntax errors.
The two queries that are currently working are
SELECT module.ModuleCode,
demonstrator.FK_Course,
slot.fk_ModuleCode,
programme.C_val,
Count(slotdemo.FK_Demonstrator) AS CountOfFK_Demonstrator
FROM programme
INNER JOIN (demonstrator
INNER JOIN (((module
INNER JOIN slot ON module.ModuleCode = slot.fk_ModuleCode))
INNER JOIN slotdemo ON slot.SlotNo = slotdemo.FK_SlotNo) ON demonstrator.StudentID = slotdemo.FK_Demonstrator) ON programme.COURSE = demonstrator.FK_Course
WHERE demonstrator.`undergraduate`=1
GROUP BY module.ModuleCode
and
SELECT week.Hour,
module.color,
module.moduleName,
module.num_ugdemos,
slot.fk_Room,
slot.fk_ModuleCode,
slottime.FK_Hour,
slottime.FK_SlotNo,
programme.C_val,
Count(slotdemo.FK_Demonstrator) AS CountOfFK_Demonstrator
FROM week
INNER JOIN ((programme
INNER JOIN ((module
INNER JOIN slot ON module.ModuleCode = slot.fk_ModuleCode)
INNER JOIN slottime ON slot.SlotNo = slottime.FK_SlotNo) ON programme.COURSE = module.FK_Course)
LEFT JOIN slotdemo ON slot.SlotNo = slotdemo.FK_SlotNo) ON week.Hour = slottime.FK_Hour
GROUP BY week.Hour,
module.ModuleCode,
module.moduleName,
module.color,
slot.SlotNo,
slot.fk_Room,
slottime.FK_Hour,
programme.C_val HAVING((programme.C_val)<9);
my preliminary attempt at combining the two is
SELECT
week.Hour,
module.color,
module.moduleName,
module.num_ugdemos,
slot.fk_Room,
slot.fk_ModuleCode,
slottime.FK_Hour,
slottime.FK_SlotNo,
programme.C_val,
Count(slotdemo.FK_Demonstrator) AS CountOfFK_Demonstrator
FROM
week
INNER JOIN
(
(
programme
INNER JOIN
(
demonstrator
INNER JOIN
(
(
(
module
INNER JOIN
slot
ON module.ModuleCode = slot.fk_ModuleCode
)
)
INNER JOIN
slotdemo
ON slot.SlotNo = slotdemo.FK_SlotNo
)
ON demonstrator.StudentID = slotdemo.FK_Demonstrator
)
ON programme.COURSE = demonstrator.FK_Course
)
ON week.Hour = slottime.FK_Hour
WHERE
demonstrator.`undergraduate`=1
GROUP BY week.Hour,
module.moduleName,
module.color,
slot.SlotNo,
slot.fk_ModuleCode,
slot.fk_Room,
slottime.FK_Hour,
programme.C_val
The error message, for what's it's worth (which is not much) is:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use
near 'ON week.Hour = slottime.FK_Hour WHERE
demonstrator.undergraduate=1 GROUP BY we' at line 17
I think you want to UNION Two datasets together. Just use the UNION operator:
(SELECT .... FROM t1)
UNION
(SELECT ... FROM t2)
Both selects should return the same columns, IF the names differ you can use AS to rename it.

use subquery in inner join mysql

This is my query
SELECT CONCAT(`SM_Title`,' ',`SM_Full_Name`) AS NAME,
`RG_Date`,
`RG_Reg_No`,
`RG_Stu_ID`,
`SM_Tell_Mobile`,
`SM_Tel_Residance`,
`RG_Reg_Type`,
Default_Batch,
`RG_Status`,
`RG_Final_Fee`,
`RG_Total_Paid`,
(`RG_Final_Fee`-`RG_Total_Paid`) AS TOTALDUE,
SUM(`SI_Ins_Amount` - `SI_Paid_Amount`) AS AS_AT_APRIAL_END
INNER JOIN
(SELECT `SI_Ins_Amount`,
`SI_Reg_No`
FROM
`student_installments`
GROUP BY MONTHNAME(`SI_Due_Date`)) Z ON
Z.`SI_Reg_No` = `registrations`.`RG_Reg_No`
FROM `registrations`
LEFT JOIN `student_master` ON `student_master`.`SM_ID` = `registrations`.`RG_Stu_ID`
LEFT JOIN `student_installments` ON `student_installments`.`SI_Reg_No` = `registrations`.`RG_Reg_No`
WHERE (`RG_Reg_Type` LIKE '%HND%' OR `RG_Reg_Type` LIKE '%LMU%' )
AND `SI_Due_Date` <= '2014-04-30' GROUP BY `SI_Reg_No`
It gave me an error near
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'Z LIMIT 0, 25' at line 1
SELECT
CONCAT(SM_Title,' ',SM_Full_Name) AS NAME,
RG_Date,
RG_Reg_No,
RG_Stu_ID,
SM_Tell_Mobile,
SM_Tel_Residance,
RG_Reg_Type,
Default_Batch,
RG_Status,
RG_Final_Fee,
RG_Total_Paid,
(RG_Final_Fee-RG_Total_Paid) AS TOTALDUE,
SUM(SI_Ins_Amount - SI_Paid_Amount) AS AS_AT_APRIAL_END
FROM registrations
INNER JOIN
(SELECT SI_Ins_Amount,SI_Reg_No
FROM student_installments
GROUP BY MONTHNAME(SI_Due_Date)) Z ON Z.SI_Reg_No = registrations.RG_Reg_No
LEFT JOIN student_master ON student_master.SM_ID = registrations.RG_Stu_ID
LEFT JOIN student_installments ON student_installments.SI_Reg_No = registrations.RG_Reg_No
WHERE (RG_Reg_Type LIKE '%HND%' OR RG_Reg_Type LIKE '%LMU%' )
AND SI_Due_Date <= '2014-04-30'
GROUP BY SI_Reg_No
I notice you have fogotten the left table or subselect that you want to join to the (SELECT SI_INs .....) and previous this I could see there is no from clause before join.
I hope this helps you
Regards
You are using from clause in wrong position it should be just after selection of your columns, you can use below query:
SELECT
CONCAT(SM_Title,' ',SM_Full_Name) AS NAME ,RG_Date,RG_Reg_No,RG_Stu_ID,SM_Tell_Mobile,SM_Tel_Residance,RG_Reg_Type,Default_Batch,RG_Status,RG_Final_Fee,RG_Total_Paid,(RG_Final_Fee-RG_Total_Paid) AS TOTALDUE, SUM(SI_Ins_Amount - SI_Paid_Amount) AS AS_AT_APRIAL_END
FROM registrations AS reg
JOIN
(SELECT
SI_Ins_Amount,SI_Reg_No
FROM student_installments
GROUP BY MONTHNAME(SI_Due_Date)) AS Z
ON Z.SI_Reg_No = reg.RG_Reg_No
LEFT JOIN student_master AS sm
ON sm.SM_ID = reg.RG_Stu_ID
LEFT JOIN student_installments AS si
ON si.SI_Reg_No = reg.RG_Reg_No
WHERE (RG_Reg_Type LIKE '%HND%' OR RG_Reg_Type LIKE '%LMU%' ) AND SI_Due_Date <= '2014-04-30'
GROUP BY SI_Reg_No;
In the part below, from keyword should go before the inner join:
FROM registrations
INNER JOIN
(SELECT SI_Ins_Amount,
SI_Reg_No
FROM student_installments
GROUP BY MONTHNAME(SI_Due_Date)
) Z
ON Z.SI_Reg_No = registrations.RG_Reg_No

MySQL / PHP - 2 different arguments for 1 table

I have the following SQL:
$queryString = "
SELECT
iR.lastModified,
d.*,
c2.title as stakeholderTitle,
u.username as authorUsername,
c.title as authorContactName,
GROUP_CONCAT(iR.stakeholderRef) AS participants
FROM
informationRelationships iR,
contacts c2
INNER JOIN
debriefs d ON
d.id = iR.linkId
LEFT JOIN
users u ON
u.id = iR.author
LEFT JOIN
contacts c ON
c.ref = u.contactId
LEFT JOIN
debriefs d2 ON
d2.stakeholder = c2.ref
WHERE
(
iR.clientRef = '$clientRef' OR
iR.contactRef = '$contactRef'
)
AND
iR.projectRef = '$projectRef' AND
iR.type = 'Debrief'
GROUP BY
iR.linkId
ORDER BY
d.dateOfEngagement
";
notice how I require 2 different bits of data for the the contacts table.
So at one point, I need to match
c.ref = u.contactId
This will return one bit of information
but I also need a completely different grouping:
d2.stakeholder = c2.ref
Problem is that the title is the column i'm interested in for both:
c2.title as stakeholderTitle,
...
c.title as authorContactName
How do I go about doing this?
My current try is returning:
Error: Unknown column 'iR.linkId' in 'on clause'
I'm not sure I really understand what is happening here:
how to join two tables on common attributes in mysql and php?
EDIT::::---ANSWERED--zerkms
$queryString = "
SELECT
iR.lastModified,
d.*,
c2.title as stakeholderTitle,
u.username as authorUsername,
c.title as authorContactName,
GROUP_CONCAT(iR.stakeholderRef) AS participants
FROM
informationRelationships iR
INNER JOIN
debriefs d ON
d.id = iR.linkId
INNER JOIN
contacts c2 ON
d.stakeholder = c2.ref
LEFT JOIN
users u ON
u.id = iR.author
LEFT JOIN
contacts c ON
c.ref = u.contactId
WHERE
(
iR.clientRef = '$clientRef' OR
iR.contactRef = '$contactRef'
)
AND
iR.projectRef = '$projectRef' AND
iR.type = 'Debrief'
GROUP BY
iR.linkId
ORDER BY
d.dateOfEngagement
";
By re-ordering my query I have managed to get both columns in... Thanks zerkms!
You cannot mix implicit joins and explicit joins in a single query in mysql.
So
FROM informationRelationships iR,
contacts c2
should be rewritten to
FROM informationRelationships iR
INNER JOIN contacts c2 ON ...
Do not use cartesian product and joins in the same query (not subquery), here, use only joins (CROSS JOIN is the same as cartesian product).