Single array where multiple should be returned - mysql

The following query in phpmyadmin returns three columns (entry_id) with three different entry ids as I need.
SELECT sub_1.entry_id, sub_2.entry_id, sub_3.entry_id
FROM exp_judging_portfolios AS jud
LEFT JOIN exp_submissions AS sub_1 ON sub_1.id = jud.rel_id_1
LEFT JOIN exp_submissions AS sub_2 ON sub_2.id = jud.rel_id_2
LEFT JOIN exp_submissions AS sub_3 ON sub_3.id = jud.rel_id_3
WHERE sub_1.member_group = $member_group
AND jud.pre = 1
GROUP BY jud.rel_id_1
However, when I return the results in page, I get a single array with just one of the entry ids.
Here is the code I am using to generate the results
$sql = "
SELECT sub_1.entry_id, sub_2.entry_id, sub_3.entry_id
FROM exp_judging_portfolios AS jud
LEFT JOIN exp_submissions AS sub_1 ON sub_1.id = jud.rel_id_1
LEFT JOIN exp_submissions AS sub_2 ON sub_2.id = jud.rel_id_2
LEFT JOIN exp_submissions AS sub_3 ON sub_3.id = jud.rel_id_3
WHERE sub_1.member_group = $member_group
AND jud.pre = 1
GROUP BY jud.rel_id_1
";
$query = $this->EE->db->query($sql);
$submissions_portfolio = $query->result_array();
print_r($submissions_portfolio);
Here is whats returned:
Array ( [0] => 354 )
Does anyone have any idea why? and if so, how to return all 3 entry ids?

The reason you only get one result this time, is because all 3 selected ids have the same alias entry_id. They end up overwriting each other.
You should try naming them differently:
SELECT sub_1.entry_id AS id_1, sub_2.entry_id AS id_2, sub_3.entry_id AS id_3

Related

MySQL: From sub query to a single query

I have this query which i believe can be optimized:
SELECT floors.id, floors.floor FROM floors
WHERE floors.societies_id = 1
AND floors.status = 'Y'
AND floors.id NOT IN (
SELECT DISTINCT(floors.id) FROM floors
INNER JOIN societies ON societies.id = floors.societies_id
INNER JOIN resident_floors ON resident_floors.floors_id = floors.id
WHERE societies.id = 1
AND floors.status = 'Y'
)
Is this query fine to use or there it can be improved..?
It looks like you want to get all floors that aren't present in resident_floors. For this we can left join RF in and ask for only rows where the join failed resulting in a null in RF:
SELECT floors.* FROM floors
INNER JOIN societies ON societies.id = floors.societies_id
LEFT JOIN resident_floors ON resident_floors.floors_id = floors.id
WHERE societies.id = 1
AND floors.status = 'Y'
AND resident_floors.floors_id IS NULL

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"

Limit MySQL results by left join

I have a MySQL query that creates an aggregate of data for an object and all of it's children in a one to many relationship. My query looks like this:
select * from object o
left join event e on o.tenant_id = e.tenant_id AND o.udid = e.udid
left join event_type et on e.event_type_id = et.event_type_id
left join event_custom_field ecf on e.event_id = ecf.event_id
left join profile p on o.tenant_id = p.tenant_id AND o.udid = p.udid
left join status s on o.tenant_id = s.tenant_id AND o.udid = s.udid
left join o_tenant_app ota on o.tenant_id = ota.tenant_id AND o.udid = ota.udid
left join tenant_app ta on ota.tenant_app_id = ta.tenant_app_id
left join heartbeat h on o.tenant_id = h.tenant_id AND o.udid = h.udid
where o.tenant_id = 'a'
AND o.checked_out = false
and p.name in ('test')
and s.status_name in ('stat1', 'stat2')
order by o.udid, e.event_id;
I need to be able to apply a limit to the number of objects returned while still including all of the other joined data. If I put the limit at the end then I will lose object data. I could do this on my first line:
select * from (select * from object limit 0,5) o
but that will show fewer than 5 objects if those first 5 objects don't match the where clause. I would like to do this as performant as possible as I will likely have millions of records to query against.

Counting groups of 3? Possible?

I have the following query that is selecting groups of entries of 3 that match and don't exist in the second table.
I need to find a way to return via 'count_result' the count of the number of groups found, not individual entry ids as below.
How can I achieve this?
SELECT COUNT(sub.entry_id) as count_result
FROM exp_submissions AS sub
LEFT JOIN exp_judging_portfolios AS jud1 ON sub.entry_id = jud1.entry_id_1
LEFT JOIN exp_judging_portfolios AS jud2 ON sub.entry_id = jud1.entry_id_2
LEFT JOIN exp_judging_portfolios AS jud3 ON sub.entry_id = jud1.entry_id_3
WHERE jud1.entry_id_1 IS NULL
AND jud2.entry_id_2 IS NULL
AND jud3.entry_id_3 IS NULL
AND sub.member_group = 6
AND sub.type_id = 1
GROUP BY sub.member_id, sub.portfolio_number
HAVING count(sub.portfolio_number) = 3
No subquery necessary.
SELECT COUNT(DISTINCT(sub.member_id, sub.portfolio_number)) as count_result
FROM exp_submissions AS sub
LEFT JOIN exp_judging_portfolios AS jud1 ON sub.entry_id = jud1.entry_id_1
LEFT JOIN exp_judging_portfolios AS jud2 ON sub.entry_id = jud1.entry_id_2
LEFT JOIN exp_judging_portfolios AS jud3 ON sub.entry_id = jud1.entry_id_3
WHERE jud1.entry_id_1 IS NULL
AND jud2.entry_id_2 IS NULL
AND jud3.entry_id_3 IS NULL
AND sub.member_group = 6
AND sub.type_id = 1
GROUP BY sub.member_id, sub.portfolio_number
HAVING count(sub.portfolio_number) = 3
Use your query as the source for another query that just counts the results:
SELECT COUNT(*) FROM (
-- YOUR QUERY GOES HERE --
) AS t

MySQL: count matching rows in second table

I want to list all teams, then count how many times each team appears in my second table. Some users are not in the second table, so the count would be zero. The problem is when I use the count function it only lists users that are in the second table. How do I count, and list 0 if they dont appear in second table?
$query = "SELECT t.id as id, t.t_name as name, t.t_city as city, (count(pd.rs)) as pd FROM #__bl_regions as r, #__bl_teams as t, #__bl_paid as pd WHERE t.id != 0 AND t.id != 1 AND (t.id IN($teams)) AND r.id = ".$t_id." AND pd.rs = 1 AND pd.t_id = ".$t_id." ORDER BY t.t_name";
$db->setQuery($query);
$players = $db->loadObjectList();
Tried Left Join
Ok, so because I am including 3 tables I believe I have to use 2 queries. Same thing is still happening, only listing schools with count. #__bl_paid is the table I want to count, #__bl_teams is the table I want to list all.
$query = "SELECT t.id as id FROM #__bl_regions as r, #__bl_teams as t WHERE t.id != 0 AND t.id != 1 AND (t.id IN($teams)) AND r.id = ".$t_id." ORDER BY t.t_name";
$db->setQuery($query);
$players1 = $db->loadResultArray();
if ($players1){
$players2 = implode(",",$players1);
}else{
$players2 = 0;
}
$query = "SELECT t.id as id, t.t_name as name, t.t_city as city, coalesce((count(pd.rs)),0) as pdc FROM #__bl_paid as pd LEFT JOIN #__bl_teams as t ON pd.t_id = t.id WHERE (t.id IN($players2)) ORDER BY t.t_name";
$db->setQuery($query);
$players = $db->loadObjectList();
You need two pieces to get what you want:
an outer join -- left join is the typical MySQL version used
a way to detect if a column is null, and if so, supply a different value. I often use coalesce
An inner join drops rows that don't have matches in the other table; a left join is similar to an inner join, but preserves all the rows in the left table, and supplies columns with null if there's no matching row in the right table.
Here's an example:
select column1, coalesce(column2, 0) as `newcolumn2`
from lefttable
left join righttable
on lefttable.something = righttable.something
What this will do: whenever column2 is null, it will be replaced with 0.
You should use LEFT JOIN statement instead of INNER JOIN.