SELECT where ID matches one of a list

evanr picture evanr · Mar 26, 2012 · Viewed 7.5k times · Source

I'm just learning the ins and outs of MYSQL queries but I've run into a roadblock with a project and I'd appreciate some help reaching a solution.

I have two tables, the first contains a reference to the entry (entry_id) and the modification associated (mod_id) as well as the category of modification it refers to (mod_name)

Table 1: exp_store_product_options

mod_id      entry_id        mod_name
3           2919            COLOR
4           2311            SIZE
5           2311            COLOR
6           3301            COLOR

the second table contains two relevant fields, mod_id and opt_name

Table 2: exp_store_product_modifiers

mod_id      opt_name
3           BLACK
4           EU 44
5           BROWN
6           BROWN

What I am trying to achieve, is a listing of all the DISTINCT opt_name fields that (through a join on the mod_id) correspond to entry_ids that I would like to pass in as a lump.

here is the code I've come up with so far, I believe it'll do what I need aside from requiring me to loop through the query for each entry id, and failing on the DISTINCT requirement since for each iteration, everything is distinct. (the {sale_products} tags are from ExpressionEngine, and will loop during the parse to provide me with a list of the entry_id results that are relevant to this page

SELECT DISTINCT opt_name
FROM exp_store_product_options
INNER JOIN exp_store_product_modifiers
ON exp_store_product_options.product_mod_id=exp_store_product_modifiers.product_mod_id
{sale_products parse='inward'}entry_id = '{entry_id}' OR{/sale_products}
AND mod_name = 'SIZE'

====================================================

POSTMORTEM

Just in case anyone else is trying to work within expresso's Store module for ExpressionEngine and needs to build some rudimentary filtering into your templates, here's the code I ultimately got to work. Very similar to Ben's code, but utilizing embeds instead of directly inserting the entry_ids because of issues with parse order:

the template: embeds/product_filter

{exp:query sql="SELECT DISTINCT opt_name
FROM exp_store_product_modifiers
LEFT JOIN exp_store_product_options
ON exp_store_product_options.product_mod_id = exp_store_product_modifiers.product_mod_id
WHERE exp_store_product_modifiers.entry_id IN ({embed:entry_ids})
AND exp_store_product_modifiers.mod_name = '{embed:filter_on}'"
}

<li><a href="#">{opt_name}</a></li>
{/exp:query}

with an {embed} that looks like

{embed="embeds/product_filter" entry_ids="{sale_products backspace='1'}{entry_id},{/sale_products}" filter_on="SIZE"}

Answer

Ben Lee picture Ben Lee · Mar 26, 2012

If you have a list of entries, you can use IN. Also, I'd use a LEFT JOIN here instead of an INNER JOIN.

SELECT DISTINCT opt_name
FROM exp_store_product_options
LEFT JOIN exp_store_product_modifiers
  ON exp_store_product_options.product_mod_id = exp_store_product_modifiers.product_mod_id
WHERE exp_store_product_options.entry_id IN (1,2,3)
AND mod_name = 'SIZE'