Issue understanding the Inner Join Or Left join - mysql

I am having an issue understanding the inner and left join
I am having the below query in the outsystems
SELECT {CLD}.[Id], {CLD}.[Name], {CLD}.[Comments]
, {CLD}.[LastUpdateOn],min({Project}.[Number])
,count({Project}.[Number])
FROM {CLD}
INNER JOIN {Project} ON {Project}.[Id] = {CLDProjects}.[ProjectId]
INNER JOIN {CLDProjects} ON {CLD}.[Id] = {CLDProjects}.[CLDId]
WHERE
(
#IsJAXPM =1
or EXISTS (SELECT 1
FROM {CLDParticipant}
WHERE {CLDParticipant}.[CLDId] = {CLD}.[Id]
AND {CLDParticipant}.[UserId] = #UserId)
or EXISTS (SELECT 1
FROM {ProjectParticipantWidget}
INNER JOIN {ProjectParticipant} ON {ProjectParticipantWidget}.[ProjectParticipantId] = {ProjectParticipant}.[Id]
WHERE {ProjectParticipant}.[ProjectId] = {Project}.[Id]
AND {ProjectParticipant}.[UserId] = #UserId)
)
GROUP BY {CLD}.[Id], {CLD}.[Name], {CLD}.[Comments], {CLD}.[LastUpdateOn]
The issue is the Select is pulling all the CLD elements without respect to the Project, I am trying to select CLD's whose Project id = Project.Id. I tried both the joins but it keep pulling all the values
Below how the structure looks like

Please try the following: First get the CLDProjects matching with Project then get the CLD from matched records.
FROM {CLD} INNER JOIN (
{CLDProjects} INNER JOIN {Project} ON {Project}.[Id] = {CLDProjects}.[ProjectId]
) ON {CLD}.[Id] = {CLDProjects}.[CLDId]

You're probably missing the inner join to CLDProjects on the ProjectParticipant subquery. Add
INNER JOIN {CLDProjects} ON {ProjectParticipant}.[ProjectId] = {CLDProjects}.[ProjectId])
on the second EXISTS join conditions, otherwise it will the second results will match the exists for every project the user is in, ignoring the other conditions over CLDProjects. Try the following:
SELECT {CLD}.[Id], {CLD}.[Name], {CLD}.[Comments]
, {CLD}.[LastUpdateOn],min({Project}.[Number])
,count({Project}.[Number])
FROM {CLD}
INNER JOIN {Project} ON {Project}.[Id] = {CLDProjects}.[ProjectId]
INNER JOIN {CLDProjects} ON {CLD}.[Id] = {CLDProjects}.[CLDId]
WHERE
(
#IsJAXPM =1
or EXISTS (SELECT 1
FROM {CLDParticipant}
WHERE {CLDParticipant}.[CLDId] = {CLD}.[Id]
AND {CLDParticipant}.[UserId] = #UserId)
or EXISTS (SELECT 1
FROM {ProjectParticipantWidget}
INNER JOIN {ProjectParticipant} ON {ProjectParticipantWidget}.[ProjectParticipantId] = {ProjectParticipant}.[Id]
INNER JOIN {CLDProjects} ON {ProjectParticipant}.[ProjectId] = {CLDProjects}.[ProjectId]
WHERE {ProjectParticipant}.[ProjectId] = {Project}.[Id]
AND {ProjectParticipant}.[UserId] = #UserId)
)
GROUP BY {CLD}.[Id], {CLD}.[Name], {CLD}.[Comments], {CLD}.[LastUpdateOn]
Also.. make sure you're not passing #IsJAXPM as 1... otherwise it will definitely return all records.
Let us know if that works. Otherwise, please extend the diagram to show the ProjectParticipant and ProjectParticipantWidget tables as well.

I think you just need to reorder your joins, I tried to reproduce your case (with incorrect joins order), but it gives me error when test the query,
but if you reorder the the joins, it works. note that I am using OutSystems 10

Related

error subquery return more than 1 when doing multiple select

I want to do a multiple select in one query with different conditions. but somehow i'm stuck in this problem. any idea?
SELECT
(select io_link_event_names.name from doors left join controller_devices on doors.iid = controller_devices.iid left join events on controller_devices.mac = events.mac left join io_link_event_names on events.iolinkerid = io_link_event_names.extra where events.iolinkerid = "9000;1") AS forced,
(select doors.name FROM doors) AS doorname
ERROR #1242 - Subquery returns more than 1 row
consider this
SELECT d.[forced], doors.name as doorname
from doors
left join (
select controller_devices.iid, io_link_event_names.name as [forced]
from events
inner join controller_devices on controller_devices.mac = events.mac
inner join io_link_event_names on events.iolinkerid = io_link_event_names.extra
where events.iolinkerid = "9000;1"
) as d on d.iid = doors.iid
If you have more than 1 row in table doors, you get this error. If you want too see door name relevant to event selected in first query, use
select io_link_event_names.name,
doors.name doorname
from doors
left join controller_devices
on doors.iid = controller_devices.iid
left join events
on controller_devices.mac = events.mac
left join io_link_event_names
on events.iolinkerid = io_link_event_names.extra
where events.iolinkerid = "9000;1"

Joining in the row with max value via a jointable

Usually when I need to join the row with some max value from another column I do something like:
SELECT *
FROM a
INNER JOIN b ON (a.aid = b.aid)
LEFT JOIN b nullb ON (a.aid = nullb.aid AND nullb.value > b.value)
WHERE nullb.bid IS NULL;
I'm not sure if this is the most efficent way but it is a solution without subqueries which i avoid whenever possible.
Today I needed to join in the max value from another table that joins in via a jointable and could not figure out a way to do it.
I tried something like this: (which failed miserably)
SELECT *
FROM a
INNER JOIN atob ON (a.aid = atob.aid)
INNER JOIN b ON (atob.bid = b.bid)
LEFT JOIN atob nullatob ON (a.aid = nullatob.aid)
LEFT JOIN b nullb ON (nullatob.bid = nullb.bid AND nullb.value > b.value)
WHERE nullb.bid IS NULL;
I set up an sqlfiddle at: http://sqlfiddle.com/#!9/86f18/6 with the problem set up.
Anyone got a clever way to join in the max value from another table via a jointable without using subqueries or is that pretty much impossible?
Not sure what is your goal but:
http://sqlfiddle.com/#!9/86f18/13
SELECT A.*, b.*
FROM A
INNER JOIN AtoB
ON (A.Aid = AtoB.Aid)
LEFT JOIN (
SELECT B.*
FROM B
LEFT JOIN b nullB
ON (B.Bid = nullB.Bid AND nullB.bdate > B.Bdate)
WHERE nullB.Bid IS NULL
) b
ON AtoB.Bid = b.Bid

mysql query very slow when adding subquery

I have below query , only 800 record taking 5 minits to run, can you some help please
SELECT
vtiger_salesorder.salesorderid,vtiger_salesorder.salesorder_no,vtiger_salesorder.sostatus,
(SELECT se.s_date
FROM
softMax_events as se
INNER JOIN vtiger_salesorder as bm ON bm.salesorderid = se.orderNum
where (bm.sostatus = 'Order' AND se.orderNum = vtiger_salesorder.salesorderid) AND se.appointTyp='60'
group by bm.salesorderid Limit 0,1) As sdate
FROM
vtiger_salesorder
Inner Join vtiger_crmentity ON vtiger_salesorder.salesorderid = vtiger_crmentity.crmid
WHERE (vtiger_salesorder.sostatus = 'Order')
and ( vtiger_crmentity.deleted<>'1')
Try this query, hope so this will help you,
SELECT vtiger_salesorder.salesorderid,vtiger_salesorder.salesorder_no,vtiger_salesorder.sostatus,se.s_date
FROM vtiger_salesorder
Inner Join vtiger_crmentity ON vtiger_salesorder.salesorderid = vtiger_crmentity.crmid
INNER JOIN softMax_events se ON se.orderNum = salesorderid
WHERE (vtiger_salesorder.sostatus = 'Order') AND/OR
se.orderNum = vtiger_salesorder.salesorderid AND se.appointTyp='60'
and ( vtiger_crmentity.deleted<>'1')
Edit:
I noticed that there is some relation between vtiger_salesorder and softMax_events and you can use a join for both table, and in this way you can remove that inner query, i tried it you may test it. this will help you for sure after a bit modification.

Hanging mysql query

I'm having an issue with the following query
select
ord.order_id,
ordProduct.product_id,
coupProd.product_id,
coup.date_end as DateEnd, coup.coupon_id
from `order` ord
inner join order_product ordProduct on ord.order_id = ordProduct.order_id
inner join coupon_product coupProd on ordProduct.product_id = coupProd.product_id
inner join coupon coup on coupProd.coupon_id = coup.coupon_id
where (coup.date_end > curdate());
If I remvove the where clause, the query executes fine, otherwise it just hangs. Any ideas?
It's not a solution per se, but as a workaround, you could maybe get it done as a nested query. i.e. ,
SELECT * FROM (
SELECT
ord.order_id,
ordProduct.product_id,
coupProd.product_id,
coup.date_end AS DateEnd, coup.coupon_id
FROM `order` ord
INNER JOIN order_product ordProduct ON ord.order_id = ordProduct.order_id
INNER JOIN coupon_product coupProd ON ordProduct.product_id = coupProd.product_id
INNER JOIN coupon coup ON coupProd.coupon_id = coup.coupon_id)
WHERE (DateEnd > CURDATE());

SQL query wrong result

i have this query:
SELECT `completed`.`ID` AS `ID`,`completed`.`level` AS `level`,`completed`.`completed_in` AS `completed_in`, COUNT(1) AS `right_answers_num`
FROM `completed`
INNER JOIN `history` ON `history`.`ID` = `completed`.`ID`
INNER JOIN `questions` ON `questions`.`ID` = `history`.`question`
WHERE `completed`.`student_id` = '1' AND `questions`.`answer` = `history`.`answer`
GROUP BY `completed`.`ID`
ORDER BY `completed`.`completed_in` DESC
what i need is to get info of each test in completed table (id,level,completed_in,right_answer_num)
the problem with that query is that if there is no one right answer(history.answer = questions.answer) then it doesn't return the row, while it should return the row(id,level,completed_in) and the right_answer_num(counter) should be zero..
please help me,, thanks ahead.
SELECT
completed.ID AS ID,
completed.level AS level,
completed.completed_in AS completed_in,
COUNT(questions.answer) AS right_answers_num
FROM completed
INNER JOIN history ON history.ID = completed.ID
LEFT JOIN questions ON questions.ID = history.question AND questions.answer = history.answer
WHERE
completed.student_id = '1'
GROUP BY
completed.ID
ORDER BY completed.completed_in DESC
use a LEFT OUTER JOIN intead of an INNER JOIN.
The second inner join is what's causing rows with no record in the questions table to be omitted. An inner join will only return rows that have data in all corresponding tables. Change the second inner join to a left join like so:
SELECT
completed.ID AS ID,
completed.level AS level,
completed.completed_in AS completed_in,
COUNT(questions.answer) AS right_answers_num
FROM completed
INNER JOIN history ON history.ID = completed.ID
LEFT JOIN questions ON questions.ID = history.question
WHERE completed.student_id = 1
GROUP BY completed.ID
ORDER BY completed.completed_in DESC