Mysql SELECT distinct Group by and Order by - mysql

I have problem with my SQL SELECT statement. I get in right order, right drivers, but my other columns are incorrect! And I can't get it right way.
I have data like this:
id, races_id, drivers_id, drive_nr, lap_nr, time, dnf
"231", "9", "41", "1", "1", "00:00:04.750", "0"
"232", "9", "41", "1", "2", "00:00:06.030", "0"
"233", "9", "41", "1", "3", "00:00:01.740", "0"
"234", "9", "42", "1", "1", "00:00:05.440", "0"
"235", "9", "42", "1", "2", "00:00:05.400", "0"
"236", "9", "42", "1", "3", "00:00:02.300", "0"
"237", "9", "43", "1", "1", "00:00:00.620", "0"
"238", "9", "43", "1", "2", "00:00:00.290", "0"
"239", "9", "43", "1", "3", "00:00:00.280", "0"
"240", "9", "44", "1", "1", "00:00:00.600", "0"
"241", "9", "44", "1", "2", "00:00:00.190", "0"
"242", "9", "44", "1", "3", "00:00:00.220", "0"
"243", "9", "45", "1", "1", "00:00:02.830", "0"
"244", "9", "45", "1", "2", "00:00:01.890", "0"
"245", "9", "45", "1", "3", "00:00:03.200", "0"
"246", "9", "46", "1", "1", "00:00:03.580", "0"
"247", "9", "46", "1", "2", "00:00:04.550", "0"
"248", "9", "46", "1", "3", "00:00:01.060", "0"
"249", "9", "47", "1", "1", "00:00:02.920", "0"
"250", "9", "47", "1", "2", "00:00:03.950", "0"
"251", "9", "47", "1", "3", "00:00:00.320", "0"
"252", "9", "48", "1", "1", "00:00:02.150", "0"
"253", "9", "48", "1", "2", "00:00:05.720", "0"
"254", "9", "48", "1", "3", "00:00:04.530", "0"
"255", "9", "49", "1", "1", "00:00:01.530", "0"
"256", "9", "49", "1", "2", "00:00:04.360", "0"
"257", "9", "49", "1", "3", "00:00:07.110", "0"
"258", "9", "50", "1", "1", "00:00:00.450", "0"
"259", "9", "50", "1", "2", "00:00:03.550", "0"
"260", "9", "50", "1", "3", "00:00:07.900", "0"
with query this:
SELECT `id` ,
`races_id` ,
`drivers_id` ,
`drive_nr` ,
`lap_nr` ,
MIN( `time` ) AS TIME,
`dnf`
FROM `laps`
WHERE `races_id` =9
GROUP BY drivers_id`
ORDER BY MIN( `time` ) ASC
I get:
id, races_id, drivers_id, drive_nr, lap_nr, time, dnf
240, 9, 44, 1, 1, 00:00:00.190, 0
237, 9, 43, 1, 1, 00:00:00.280, 0
249, 9, 47, 1, 1, 00:00:00.320, 0
258, 9, 50, 1, 1, 00:00:00.450, 0
246, 9, 46, 1, 1, 00:00:01.060, 0
255, 9, 49, 1, 1, 00:00:01.530, 0
231, 9, 41, 1, 1, 00:00:01.740, 0
243, 9, 45, 1, 1, 00:00:01.890, 0
252, 9, 48, 1, 1, 00:00:02.150, 0
234, 9, 42, 1, 1, 00:00:02.300, 0
so I get correct time column in correct order, but not others columns like ID, drive_nr, lap_nr, dnf
how to fix my query to get distinct drivers_id with min time with correct other data?

And if you remove "GROUP BY"
SELECT `id` , `races_id` , `drivers_id` , `drive_nr` , `lap_nr` , MIN( `time` ) AS TIME, `dnf` FROM `laps` WHERE `races_id` = 9 ORDER BY MIN( `time` ) ASC
Take a look on this link, use of group by and min

The problem is that GROUP BY groups rows together for an aggregate function. In standard SQL every column returned must be a mentioned in the group by clause or an aggregate field, but MySQL extends this.
However although MySQL does allow extra columns to be returned, it does not specify which row the value of those columns comes from. While there is a pattern (seems to be the last row inserted I think), this is not defined and could change.
To get the other fields you have a couple of options.
Simplest is to have a sub query that gets the driver id and the min time for a lap for that driver id, then join that back against the laps table (joining on the driver id and the time) top get the values of the others fields for the matching row. There are a couple of minor downs sides to this. Firstly MySQL will not use an index on the fields on the sub query to join to the main table, but with limited data probably not an issue (beyond the annoyance of the queries popping up in the slow query log). The 2nd issue is if someone has a best lap time shared between 2 laps.
Simple example of the sql:-
SELECT a.id,
a.races_id,
a.drivers_id,
a.drive_nr,
a.lap_nr,
mt.min_time,
a.dnf
FROM laps a
INNER JOIN
(
SELECT drivers_id ,
MIN( `time` ) AS min_time
FROM laps
WHERE races_id = 9
GROUP BY drivers_id
) mt
ON a.drivers_id = mt.drivers_id
AND a.`time` = mt.min_time
WHERE a.races_id = 9
ORDER BY min_time ASC
If you do have 2 laps with the same min lap time then you need to specify which ones details to return (or you might not care, and could just misuse GROUP BY on the outer query as well).
A second solution is that you generate a sequence number for each row on the results ordered by driver id and lap time, resetting the sequence number on change of driver id. Then discard any lap which does not have a sequence of 1. However harder to read, and likely to be very slow when you have lots of data.
Example as follows (not tested):-
SELECT id,
races_id,
drivers_id,
drive_nr,
lap_nr,
`time`,
dnf
FROM
(
SELECT id,
races_id,
drivers_id,
drive_nr,
lap_nr,
`time`,
dnf,
#ctr := IF(drivers_id = #did, #ctr + 1, 1) AS ctr,
#did := drivers_id
FROM
(
SELECT id,
races_id,
drivers_id,
drive_nr,
lap_nr,
`time`,
dnf
FROM laps
WHERE races_id = 9
ORDER BY drivers_id, `time`
)
CROSS JOIN
(
SELECT #ctr := 0, #did := 0
) sub1
) sub2
WHERE ctr = 1
ORDER BY `time`

Related

How to get array/object number value in postgreSQL?

Is it possible to get array/object number values.
I have a table called tableA:
create table "tableA" (
"_id" serial,
"userId" integer,
"dependentData" jsonb);
INSERT INTO "tableA"
("_id", "userId", "dependentData")
VALUES('55555', '1191', '[{"_id": 133, "type": "radio", "title": "questionTest7", "question": "questionTest7", "response": {"value": ["option_11"]}, "dependentQuestionResponse": [{"_id": 278, "type": "text", "title": "questionTest8", "question": "questionTest8", "response": {"value": ["street no 140"]}, "dependentQuestionResponse": []}]}, {"_id": 154, "type": "dropdown", "title": "questionTest8", "question": "questionTest8", "response": {"value": ["option_14"]}, "dependentQuestionResponse": []}]');
Array number is to be fetched. Output should be require below.
_id
userId
array/object
55555
1191
[0,0,1]
You can try something like this
select id, user_id,
(
with
base as (
select o1, oo1.a oo1 from (
select jsonb_array_elements(t.a) o1
from (select depend_data as a) t
) o
left join lateral (select a from jsonb_array_elements(o.o1-> 'dependentQuestionResponse') a) oo1 on true
)
select json_agg(nn) from (
select dense_rank() over(order by b.o1) - 1 nn, b.o1 from base b
union all
select dense_rank() over(order by b.o1) - 1 nn, b.oo1 from base b where oo1 is not null
order by nn
) tz
) as array_object
from
(select 55555 as id,
1191 as user_id,
'[{"_id": 133, "type": "radio", "title": "questionTest7", "question": "questionTest7", "response": {"value": ["option_11"]}, "dependentQuestionResponse": [
{"_id": 278, "type": "text", "title": "questionTest8", "question": "questionTest8", "response": {"value": ["street no 140"]},"dependentQuestionResponse": []}]},
{"_id": 154, "type": "dropdown", "title": "questionTest8", "question": "questionTest8", "response": {"value": ["option_14"]}, "dependentQuestionResponse": []}]'::jsonb as depend_data) t

json_search and json_remove in mysql

notice
[
{
"date": "2022. 10. 16.",
"type": 3,
"title": "friend",
"content": "JJ friend",
"parameter": "test"
},
{
"date": "2022. 10. 16.",
"type": 3,
"title": "friend",
"content": "testtest friend",
"parameter": "test1"
}
]
I wanna search and remove in json {"date": "2022. 10. 16.","type": 3,"title": "friend","content": "testtest friend","parameter": "test1"} where id = 'test2'
There's a separate column for the ID.
update UserTable set notice = json_remove(notice, json_search(notice, 'one',
'{"date": "2022. 10. 16.","type": 3,"title": "friend","content": "testtest friend","parameter": "test1"}')) where id = 'test2'";
SELECT JSON_ARRAYAGG(jsonvalue)
FROM src_table
CROSS JOIN JSON_TABLE(src_table.notice,
'$[*]' COLUMNS (jsonvalue JSON PATH '$')) jsontable
WHERE jsonvalue <> CAST('{"date": "2022. 10. 16.","type": 3,"title": "friend","content": "testtest friend","parameter": "test1"}' AS JSON)

Query a JSONB object array

I did a DB Fiddle of what the table is kinda looking like https://www.db-fiddle.com/f/4jyoMCicNSZpjMt4jFYoz5/3382
Data in the table looks like this
[
{
"id": 1,
"form_id": 1,
"questionnaire_response": [
{
"id": "1",
"title": "Are you alive?",
"value": "Yes",
"form_id": 0,
"shortTitle": "",
"description": ""
},
{
"id": "2",
"title": "Did you sleep good?",
"value": "No",
"form_id": 0,
"shortTitle": "",
"description": ""
},
{
"id": "3",
"title": "Whats favorite color(s)?",
"value": [
"Red",
"Blue"
],
"form_id": 0,
"shortTitle": "",
"description": ""
}
]
},
{
"id": 2,
"form_id": 1,
"questionnaire_response": [
{
"id": "1",
"title": "Are you alive?",
"value": "Yes",
"form_id": 0,
"shortTitle": "",
"description": ""
},
{
"id": "2",
"title": "Did you sleep good?",
"value": "Yes",
"form_id": 0,
"shortTitle": "",
"description": ""
},
{
"id": "3",
"title": "Whats favorite color(s)?",
"value": "Black",
"form_id": 0,
"shortTitle": "",
"description": ""
}
]
},
{
"id": 3,
"form_id": 1,
"questionnaire_response": [
{
"id": "1",
"title": "Are you alive?",
"value": "Yes",
"form_id": 0,
"shortTitle": "",
"description": ""
},
{
"id": "2",
"title": "Did you sleep good?",
"value": "No",
"form_id": 0,
"shortTitle": "",
"description": ""
},
{
"id": "3",
"title": "Whats favorite color(s)?",
"value": [
"Black",
"Red"
],
"form_id": 0,
"shortTitle": "",
"description": ""
}
]
}
]
I have a query select * from form_responses,jsonb_to_recordset(form_responses.questionnaire_response) as items(value text, id text) where (items.id = '3' AND items.value like '%Black%');
But unable to do more than one object like select * from form_responses,jsonb_to_recordset(form_responses.questionnaire_response) as items(value text, id text) where (items.id = '3' AND items.value like '%Black%') AND (items.id = '2' AND items.value like '%Yes%');
The value field in the object could be an array or a single value also.. unpredictable.. I feel like I'm close but also not sure if im using the correct query in the first place.
Any help would be appreciated!
EDIT
select * from form_responses where(
questionnaire_response #> '[{"id": "2", "value":"No"},{"id": "3", "value":["Red"]}]')
Seems to work but not sure if this is the best way to do it
Your current query returns one result row per item. None of these rows has both id = 3 and id = 2. If your goal is to select the entire form response, you need to use a subquery (or rather, two of them):
SELECT *
FROM form_responses
WHERE EXISTS(
SELECT *
FROM jsonb_to_recordset(form_responses.questionnaire_response) as items(value text, id text)
WHERE items.id = '3'
AND items.value like '%Black%'
)
AND EXISTS(
SELECT *
FROM jsonb_to_recordset(form_responses.questionnaire_response) as items(value text, id text)
WHERE items.id = '2'
AND items.value like '%Yes%'
);
or alternatively
SELECT *
FROM form_responses
WHERE (
SELECT value
FROM jsonb_to_recordset(form_responses.questionnaire_response) as items(value text, id text)
WHERE items.id = '3'
) like '%Black%'
AND (
SELECT value
FROM jsonb_to_recordset(form_responses.questionnaire_response) as items(value text, id text)
WHERE items.id = '2'
) like '%Yes%';
A nicer alternative would be using json path queries:
SELECT *
FROM form_responses
WHERE questionnaire_response ## '$[*]?(#.id == "1").value == "Yes"'
AND questionnaire_response ## '$[*]?(#.id == "3").value[*] == "Black"'
-- in one:
SELECT *
FROM form_responses
WHERE questionnaire_response ## '$[*]?(#.id == "1").value == "Yes" && $[*]?(#.id == "3").value[*] == "Black"'
The [*] even has the correct semantics for that sometimes-string-sometimes-array value. And if you know the indices of the items with those ids, you can even simplify to
SELECT *
FROM form_responses
WHERE questionnaire_response ## '$[0].value == "Yes" && $[2].value[*] == "Black"'
(dbfiddle demo)

How to generate nested nth level JSON object in T-SQL?

I have below data
against below query
declare #t table
(
Id int identity,
name varchar(50),
rootid int,
level int
);
insert into #t(name, rootid, level)
values
('Home', 0, 0)
,('Transaction', 0, 0)
, ('Settings', 0, 0)
,('Purchase Request', 2, 1)
,('Purchase Order', 2, 1)
,('Inventory', 2, 1)
,('Payment Advice', 2, 1)
,('Setup', 3, 1)
,('Budget', 3, 1)
,('CRC', 3, 1)
,('Create PR', 4, 3);
select * from #t;
Desire output:
[{
"Id": 1,
"name": "Home",
"rootid": 0,
"level": 0
}, {
"Id": 2,
"name": "Transaction",
"rootid": 0,
"level": 0,
"children": [{
"Id": 4,
"name": "Purchase Request",
"rootid": 2,
"level": 1,
"children": [{
"Id": 11,
"name": "Create PR",
"rootid": 4,
"level": 3
}]
}, {
"Id": 5,
"name": "Purchase Order",
"rootid": 2,
"level": 1
}, {
"Id": 6,
"name": "Inventory",
"rootid": 2,
"level": 1
}, {
"Id": 7,
"name": "Payment Advice",
"rootid": 2,
"level": 1
}]
}, {
"Id": 3,
"name": "Settings",
"rootid": 0,
"level": 0,
"children": [{
"Id": 8,
"name": "Setup",
"rootid": 3,
"level": 1
}, {
"Id": 9,
"name": "Budget",
"rootid": 3,
"level": 1
}, {
"Id": 10,
"name": "CRC",
"rootid": 3,
"level": 1
}]
}]
Also Tried #Iptr answer:
;WITH result (id, name, rootId, parent, Level) AS
(
SELECT id,
name,
RootId,
Id as Parent,
0 as Level
FROM #t
WHERE RootId= 0
UNION ALL
SELECT t.id,
t.Name,
t.RootId,
r.Parent,
r.Level + 1
FROM #t t
INNER JOIN result r ON r.id = t.RootId
)
SELECT t.*, json_query(nullif(c.children, '[{}]')) as children
FROM #t as t
outer apply (
select
(
select r.*
from result as r
where r.parent = t.Id
and r.level > 0
order by r.id
for json auto
) as children
) as c
where t.level = 0
order by t.Level
for json auto;
Output
[{
"Id": 1,
"name": "Home",
"rootid": 0,
"level": 0
}, {
"Id": 2,
"name": "Transaction",
"rootid": 0,
"level": 0,
"children": [{
"id": 4,
"name": "Purchase Request",
"rootId": 2,
"parent": 2,
"Level": 1
}, {
"id": 5,
"name": "Purchase Order",
"rootId": 2,
"parent": 2,
"Level": 1
}, {
"id": 6,
"name": "Inventory",
"rootId": 2,
"parent": 2,
"Level": 1
}, {
"id": 7,
"name": "Payment Advice",
"rootId": 2,
"parent": 2,
"Level": 1
}, {
"id": 11,
"name": "Create PR",
"rootId": 4,
"parent": 2,
"Level": 2
}]
}, {
"Id": 3,
"name": "Settings",
"rootid": 0,
"level": 0,
"children": [{
"id": 8,
"name": "Setup",
"rootId": 3,
"parent": 3,
"Level": 1
}, {
"id": 9,
"name": "Budget",
"rootId": 3,
"parent": 3,
"Level": 1
}, {
"id": 10,
"name": "CRC",
"rootId": 3,
"parent": 3,
"Level": 1
}]
}]
Above query is not returning nth json child objects, let say if I have nth level of menu items, Parent have multiple Childs and Childs have multiple Childs like treeview.
Tried #Naveen Arora answer:
select ID,name,'' as id,'' as name from Navigations where id not in (select rootid from Navigations) and rootid=0
union
select B.id,B.name,A.id,A.name from Navigations A join Navigations B on A.rootid=B.id
FOR JSON AUTO;
But output
[{
"ID": 1,
"name": "Home",
"id": 0,
"name": ""
}, {
"ID": 2,
"name": "Transaction",
"id": 4,
"name": "Create PR"
}, {
"ID": 2,
"name": "Transaction",
"id": 5,
"name": "Generate PO"
}, {
"ID": 2,
"name": "Transaction",
"id": 6,
"name": "Create Receipt"
}, {
"ID": 2,
"name": "Transaction",
"id": 7,
"name": "Create Issue Request"
}, {
"ID": 2,
"name": "Transaction",
"id": 8,
"name": "Create Issue Note"
}, {
"ID": 2,
"name": "Transaction",
"id": 9,
"name": "Approve Payment Advice"
}, {
"ID": 3,
"name": "Settings",
"id": 11,
"name": "Navigation Management"
}, {
"ID": 11,
"name": "Navigation Management",
"id": 12,
"name": "Navigation & Form Mapping"
}]
Above output it's not include Childs node. Like in Settings I have Navigation Management -> Navigation & Form Mapping
If the sql server version is 2016 or newer than 2016 then you can use FOR JSON PATH.
Assuming that results are stored in test table. This is just to give you an idea how you can do this, may not give you the exact output but you can change it as per your requirement.
SELECT
t.Id AS 'Id',
t.Name AS 'Name',
children = (
SELECT A.id,A.name from test A join test B on A.rootid=B.id
FOR JSON PATH
)
FROM Test t
FOR JSON PATH;
And if it is older than 2016 then you may refer this.
declare #t table
(
Id int identity,
name varchar(50),
rootid int,
level int
);
insert into #t(name, rootid, level)
values
('Home', 0, 0),('Transaction', 0, 0), ('Settings', 0, 0),
('Create PR', 2, 1), ('Generate PO', 2, 1), ('Create Receipt', 2, 1), ('Create Issue Request', 2, 1), ('Create Issue Note', 2, 1), ('Approve Payment Advice', 2, 1),
('Navigation Management', 3, 1), ('Navigation & Form Mapping', 3, 1);
select * from #t;
;WITH result (id, name, rootId, parent, Level) AS
(
SELECT id,
name,
RootId,
Id as Parent,
0 as Level
FROM #t
WHERE RootId= 0
UNION ALL
SELECT t.id,
t.Name,
t.RootId,
r.Parent,
r.Level + 1
FROM #t t
INNER JOIN result r ON r.id = t.RootId
)
SELECT t.*, json_query(nullif(c.children, '[{}]')) as children
FROM #t as t
outer apply (
select
(
select r.*
from result as r
where r.parent = t.Id
and r.level > 0
order by r.id
for json auto
) as children
) as c
where t.level = 0
order by t.Level
for json auto;
SELECT t.*, json_query(nullif(c.children, '[{}]')) as children
FROM #t as t
outer apply (
select
(
select r.*
from #t as r
where r.rootid = t.Id
and r.level > 0
order by r.id
for json auto
) as children
) as c
where t.level = 0
order by t.Level
for json auto;
My apology for late posting my answer. But I really appreciate the efforts of #Iptr and #NaveenArora answer on my post. After I do some brain storming on my case I've finally found the way to do it.
Create this function:
create function [dbo].[fnUDFCreateJSON](#currentId int)
returns varchar(max)
begin
declare #json nvarchar(max)
IF #currentId <> 0
BEGIN
set #json =
(
select [ID], [Name], CSSClass, RouteURL, json_query(dbo.fnUDFCreateJSON([ID])) as SubNavigation
from dbo.Navigations
where RootId = #currentId
for json auto
);
END
ELSE
BEGIN
set #json =
(
select [ID], [Name], CSSClass, RouteURL, '' as SubNavigation from dbo.Navigations where RootId = 0
for json auto
);
END
return #json
end
and call it by using stored procedure:
CREATE PROCEDURE [dbo].[spGetStartupNavigations]
AS
BEGIN
SELECT
(SELECT
ID, Name, CSSClass, RouteURL,
JSON_QUERY (dbo.fnUDFCreateJSON(ID)) AS SubNavigation
FROM
dbo.Navigations
WHERE
RootId = 0
FOR JSON AUTO) AS Navigation
END
That's it.

How to make a JOIN with table containing attribute value zero?

I have a table that I defined one column to receive zero 0 as value. I did this because zero 0 represents all values. The table's name is agendas and the column it's turmas_id, this column has relationship with table turmas but turmas_id in agendas it's not a foreignkey because I can add 0 as saied before.
The problem is when I make a JOIN using these tables because I need return all attributes with zero value and valid keys added in table turmas.
I tried use LEFT JOIN and INNER JOIN but the result it's not what I wait. I can use JOIN if id exists in table turmas and table agendas because it's a valid foreign key but I can't return other values with 0 in agendas attribute turmas_id and this is exactly what I need.
How could I do this ?
I need display this result
//table agendas
-----------------------------------------
turmas_id | descricao
-----------------------------------------
0 | this attribute contain zero and it's not exists in table turmas
16 | table turmas contain id 16 it is a foreign key
0 | this attribute contain zero and it's not exists in table turmas
23 | table turmas contain id 23 it is a foreign key
SQL
$agendamentos = $this->Agenda->query("SELECT * FROM responsavel_alunos RespAlunos "
. "INNER JOIN pessoas Responsavel ON (Responsavel.id = RespAlunos.pessoas_id) "
. "INNER JOIN pessoas Aluno ON (Aluno.id = RespAlunos.pessoas_id1) "
. "INNER JOIN matriculas Matricula ON (Matricula.pessoas_id = Aluno.id) "
. "RIGHT JOIN turmas Turma ON (Turma.id = Matricula.turmas_id OR Turma.id = 0) "
. "INNER JOIN escolas Escola ON (Escola.id = Matricula.escolas_id) "
. "INNER JOIN agendas Agenda ON (Agenda.turmas_id = Turma.id) "
. "WHERE Responsavel.id = ? ORDER BY Agenda.created DESC "
, array($id)); //id do responsavel
Model
JSON result
{
"status": "1",
"result": [
{
"RespAlunos": {
"id": "5",
"pessoas_id": "8",
"pessoas_id1": "9",
"created": "2015-09-21 10:25:46",
"modified": "2015-09-21 10:25:46"
},
"Responsavel": {
"id": "8",
"nome": "responsavel ",
"email": "responsavel #hotmail.com",
"tipopessoas_id": "3",
"status": "1",
"created": "2015-09-21 10:17:17",
"modified": "2015-09-21 10:17:17"
},
"Aluno": {
"id": "9",
"nome": "aluno",
"email": "aluno#gmail.com",
"tipopessoas_id": "1",
"status": "1",
"created": "2015-09-21 10:18:41",
"modified": "2015-09-21 10:18:41"
},
"Matricula": {
"id": "6",
"referencia": "238",
"pessoas_id": "9",
"turmas_id": "4",
"escolas_id": "2",
"status": "1",
"created": "2015-09-21 10:35:08",
"modified": "2016-02-18 10:51:20"
},
"Turma": {
"id": "4",
"descricao": "4º ano",
"created": "2015-09-21 10:31:32",
"modified": "2015-09-21 10:31:32"
},
"Escola": {
"id": "2",
"descricao": "Santa Luz Unidade 2",
"created": "2015-09-17 23:09:38",
"modified": "2015-09-17 23:09:38"
},
"Agenda": {
"id": "34",
"data": "2016-02-29 14:40:00",
"descricao": "<p>teste 1</p>\r\n",
"escolas_id": "2",
"turmas_id": "4",
"created": "2016-02-29 14:40:21",
"modified": "2016-02-29 14:40:21"
}
},
{
"RespAlunos": {
"id": "5",
"pessoas_id": "8",
"pessoas_id1": "9",
"created": "2015-09-21 10:25:46",
"modified": "2015-09-21 10:25:46"
},
"Responsavel": {
"id": "8",
"nome": "responsavel ",
"email": "responsavel #hotmail.com",
"tipopessoas_id": "3",
"status": "1",
"created": "2015-09-21 10:17:17",
"modified": "2015-09-21 10:17:17"
},
"Aluno": {
"id": "9",
"nome": "aluno",
"email": "aluno#gmail.com",
"tipopessoas_id": "1",
"status": "1",
"created": "2015-09-21 10:18:41",
"modified": "2015-09-21 10:18:41"
},
"Matricula": {
"id": "6",
"referencia": "238",
"pessoas_id": "9",
"turmas_id": "4",
"escolas_id": "2",
"status": "1",
"created": "2015-09-21 10:35:08",
"modified": "2016-02-18 10:51:20"
},
"Turma": {
"id": "4",
"descricao": "4º ano",
"created": "2015-09-21 10:31:32",
"modified": "2015-09-21 10:31:32"
},
"Escola": {
"id": "2",
"descricao": "Santa Luz Unidade 2",
"created": "2015-09-17 23:09:38",
"modified": "2015-09-17 23:09:38"
},
"Agenda": {
"id": "27",
"data": "2016-02-29 08:24:00",
"descricao": "descricao",
"escolas_id": "2",
"turmas_id": "4",
"created": "2016-02-29 08:25:20",
"modified": "2016-02-29 08:25:20"
}
}
]
}
try to use IN ? instead of using = ? in your WHERE clause since your using an array variable
Can you try RIGHT JOIN instead?
"RIGHT JOIN turmas Turma ON (Turma.id = Matricula.turmas_id OR Turma.id = 0)"
because TABLE1 LEFT JOIN TABLE2 means all rows from TABLE1 will be selected, even if there are no matching rows in TABLE2.
RIGHT JOIN is the opposite of it. So use RIGHT JOIN so that you can return your TURMA records based from the ON condition, even if there are no matching records from the preceding table.
Try this one.
$agendamentos = $this->Agenda->query("SELECT * FROM responsavel_alunos RespAlunos "
. "INNER JOIN pessoas Responsavel ON (Responsavel.id = RespAlunos.pessoas_id) "
. "INNER JOIN pessoas Aluno ON (Aluno.id = RespAlunos.pessoas_id1) "
. "INNER JOIN matriculas Matricula ON (Matricula.pessoas_id = Aluno.id) "
. "(SELECT turmas as turma WHERE (turma.id = Matricula.turmas_id OR turma.id = 0)) AS TURMA"
. "INNER JOIN escolas Escola ON (Escola.id = Matricula.escolas_id) "
. "INNER JOIN agendas Agenda ON (Agenda.turmas_id = Turma.id) "
. "WHERE Responsavel.id IN ? ORDER BY Agenda.created DESC "
, array($id)); //id do responsavel