Sokan elkövetik azt a hibát, hogy a MySQL lekéréseket PHP ciklusba teszik, mert másképpen szerintük nem megoldható, hogy több soros eredményt tegyünk bele 1 SQL cellába a lekérdezés eredményénél. Ez a rossz módszer természetesen nagyon erőforrás pazarló és a weboldalak sebesség problémáinak nagy részét is ez okozza.
Az egyik jó megoldás ennek elkerülésére, ha a GROUP_CONCAT() paranccsal egyesítjük a subquery sorait. Viszont alapértelmezetten ebbe csak viszonyag rövid eredmény fér, így nagy eséllyel le lesz vágva a válasz vége. A méret néveléshez adjuk ki az SQL kérés előtt a következő parancsot:
SET SESSION group_concat_max_len = 100000;
Például így lehet nem JSON képes ( 🙁 ) MariaDB-ből JSON tömböt csinálni – kicsit csúnyán – egy subqueryben:
SELECT DISTINCT(rcc.company_parent_id) AS ID, c.compname AS Name, CONCAT( '[', GROUP_CONCAT( ( SELECT CONCAT('{"ID":', c2.oid, ',"Name":"', c2.compname, '","LangCode":', c2.langcode, '}') FROM companies c2 WHERE c2.oid = rcc.company_child_id AND c2.is_disabled = 0 ) ), ']' ) AS CompanyChildren FROM rel_company_company rcc LEFT OUTER JOIN companies c ON c.oid = rcc.company_parent_id WHERE FIND_IN_SET( 'device_media_share', ret_type ) AND c.is_disabled = 0
Például részlet PDO-s változatból:
$DB->exec('SET SESSION group_concat_max_len = 100000;'); $q = <<<SQL SELECT DISTINCT(rcc.company_parent_id) AS ID, c.compname AS Name, CONCAT( '[', GROUP_CONCAT( ( SELECT CONCAT('{"ID":', c2.oid, ',"Name":"', c2.compname, '","LangCode":', c2.langcode, '}') FROM companies c2 WHERE c2.oid = rcc.company_child_id AND c2.is_disabled = 0 ) ), ']' ) AS CompanyChildren FROM rel_company_company rcc LEFT OUTER JOIN companies c ON c.oid = rcc.company_parent_id WHERE FIND_IN_SET( 'device_media_share', ret_type ) AND c.is_disabled = 0 SQL; $st = $DB->prepare(trim($q)); $st->execute([]); $ret->result = $st->fetchAll(PDO::FETCH_OBJ); foreach($ret->result as $r) { $r->CompanyChildren = json_decode($r->CompanyChildren); } echo json_encode($ret); ...