MySQL group certain results into an array
I don't think MySQL can return an array to PHP, but it can return a delimited list using the GROUP_CONCAT aggregate function. Try something like:
SELECT user_id, firstname, lastname,
GROUP_CONCAT(wp_usermeta.meta_value) as target_employer_id
FROM `wsat_ib`
LEFT JOIN wp_usermeta ON
(wsat_ib.user_id = wp_usermeta.user_id
AND wp_usermeta.meta_key = 'target_employer')
GROUP BY user_id, firstname, lastname
By default you should get a comma-separated list of elements in target_employer_id
. You can use the PHP explode
function to turn that into an array in your PHP logic.
emersonthis
I am a designer, developer, and problem solver. I make websites and stuff. I work with brazen startups, modest individuals, earnest small business, and everyone in between. I care as much about how things look as how they work. I enjoy writing and teaching what I know. The best part about my job is constantly learning new things.
Updated on December 28, 2020Comments
-
emersonthis over 3 years
I'm writing a complex MySQL query with multiple
LEFT JOIN
s to combine data from several different tables.$public_query = "SELECT * FROM `wsat_ib` LEFT JOIN wp_usermeta ON wsat_ib.user_id = wp_usermeta.user_id LEFT JOIN wpjb_resume ON wsat_ib.user_id = wpjb_resume.user_id LEFT JOIN wpjb_field_value ON wpjb_resume.id=wpjb_field_value.job_id LEFT JOIN wpjb_application ON wpjb_application.user_id = wsat_ib.user_id WHERE wp_usermeta.meta_key = 'target_employer' AND wp_usermeta.meta_value = 'public' AND wpjb_resume.is_active =1 ";
My problem: The table wp_usermeta can have multiple rows for the same user_id. For example a user (with user_id = 5) may have more then one row in the table wp_usermeta with the field: meta_key that is 'target_employer'. In case that's not clear, the rows might look like this.
id user_id meta_key meta_value 1 5 target_employer 13 2 5 target_employer 53 3 79 target_employer 21
My Question: Is there any way that I can return each matching row from wp_usermeta as an array in one of my result objects? So the
var_dump()
would look something like this:object(stdClass)#2906 (14) { ["user_id"]=> string(4) "5" ["firstname"]=> string(6) "Bilbo" ["lastname"]=> string(3) "Baggins" ... ["target_employer"]=> array(2) { [0]=>13, [1]=>53 } }
UPDATE: @bpanulla: Here's the real (unsimplified query)...
"SELECT wsat_ib.user_id, wpjb_resume.firstname, wpjb_resume.lastname, wsat_ib.overall_score, wsat_ib.account_score, wsat_ib.econ_score, wsat_ib.math_score, wsat_ib.logic_score, wsat_ib.fsanaly_score, wsat_ib.corpval_score, wsat_ib.end_time, GROUP_CONCAT(wp_usermeta.meta_value) AS target_employers, wpjb_field_value.value AS school, wpjb_application.job_id FROM `wsat_ib` LEFT JOIN wp_usermeta ON wsat_ib.user_id = wp_usermeta.user_id LEFT JOIN wpjb_resume ON wsat_ib.user_id = wpjb_resume.user_id LEFT JOIN wpjb_field_value ON wpjb_resume.id=wpjb_field_value.job_id LEFT JOIN wpjb_application ON wpjb_application.user_id = wsat_ib.user_id AND wpjb_application.field_id=3 WHERE (wp_usermeta.meta_key = 'target_employer' AND wp_usermeta.meta_value = 'public' AND wpjb_resume.is_active =1) GROUP BY user_id ";
-
emersonthis over 11 yearsI've almost got this working, but I'm struggling with the
GROUP BY
. I get the expected number of rows returned, but I'm confused by why I'm getting multiple duplicates in the target_employer field. Even though most of my users have only one target employer, I see somewhere between 1 and 12 employer ids in each row returned. Most are repeats of the same value, which is strange because duplicate key/value pairs are not allowed in the wp_usermeta table. Any advice? -
bpanulla over 11 yearsThe GROUP_CONCAT function takes a few extra parameters that can help in cases like these (see the doc page I linked). In particular, try
GROUP_CONCAT(DISTINCT wp_usermeta.meta_value)
to get a unique list. I am a bit puzzled that there would be duplicates, unless you've added more tables to the mix and are getting multiplied rows from the joins. -
emersonthis over 11 yearsI think that is what's happening. I did leave off a couple tables in my example to make the question more readable. I added the real query to the question (above).
-
bpanulla over 11 yearsEvery field that you output in the SELECT clause of your query generally needs to appear in the GROUP BY clause, unless you're using it in an aggregate function expression (like GROUP_CONCAT). There are exceptions to this made by some DB servers, including MySQL, but that's the general rule. Add the extra fields to the GROUP BY and that may eliminate the extra rows. So a SELECT * query will generally hamper using aggregate functions.
-
emersonthis over 11 yearsThat seemed to be the problem. I had additional
SELECT
s that were causing duplication (aka "cartesian products"?). Adding them to theGROUP BY
fixed that. But I have one final question: Can add a secondGROUP_CONCAT
? I'm testing it and it works BUT my previous problem returns (duplicates in the target_employer field). -
bpanulla over 11 yearsOnly if you are grouping by the same set of fields. Think of
GROUP_CONCAT()
exactly like you wouldSUM()
,AVG()
, orCOUNT()
. You could in principle add another copy ofwp_usermeta
joined to get another meta variable andGROUP_CONCAT()
thosemeta_value
s too, as long as you grouped by the same fields.