简体   繁体   中英

MySQL query returns more rows than intended, how do i only return the highest value of one column from each group?

This query needs to return all rows with the highest value of 'revision' column out of each group of 'sheet_ID' column. It works fine when i do not do the OR statement but i need to be able to use them. The input field is for 'Item Numbers' and the or statement needs to pull that number from a possible of 10 columns where it can be.

Here is my Query statement:

SELECT item_no, item_no1, item_no2, item_no3, item_no4, item_no5, item_no6,
       item_no7, item_no8, item_no9, style, vendor_code, pgc, buyer, brand,
       product_name, sheet_ID, revision, id
FROM product_sheets
WHERE item_no LIKE '$value' or item_no1 LIKE '$value' or
      item_no2 LIKE '$value' or item_no3 LIKE '$value' or
      item_no4 LIKE '$value' or item_no5 LIKE '$value' or 
      item_no6 LIKE '$value' or item_no7 LIKE '$value' or
      item_no8 LIKE '$value' or item_no9 LIKE '$value' AND
      revision IN (SELECT MAX(revision)
                   FROM product_sheets
                   GROUP BY sheet_ID
                  );

Instead of this:

 revision IN (SELECT MAX(revision)
               FROM product_sheets
               GROUP BY sheet_ID
              );

You want a correlated subquery. In your case, you can write it as:

 revision = (SELECT MAX(ps2.revision)
              FROM product_sheets ps2
              WHERE ps2.sheet_ID = product_sheets.sheet_ID
             );

However, I would strongly advise you to use a table alias in the outer query.

You also need to fix the parentheses in the where :

WHERE (item_no LIKE '$value' or item_no1 LIKE '$value' or
       item_no2 LIKE '$value' or item_no3 LIKE '$value' or
       item_no4 LIKE '$value' or item_no5 LIKE '$value' or 
       item_no6 LIKE '$value' or item_no7 LIKE '$value' or
       item_no8 LIKE '$value' or item_no9 LIKE '$value'
      ) AND
      revision = (SELECT MAX(ps2.revision)
                  FROM product_sheets ps2
                  WHERE ps2.sheet_ID = product_sheets.sheet_ID
                 );

If $value doesn't use wildcards, this is much more simply written as:

where '$value' in (item_no, item_no1, item_no2, . . .) and
      revision = (SELECT MAX(ps2.revision)
                  FROM product_sheets ps2
                  WHERE ps2.sheet_ID = product_sheets.sheet_ID
                 );

And, in addition to the comment about normalization (which is strongly suggested), you also need to learn about using query parameters to pass in values to a query.

You must use brackets around th or conditions, without them only the last condition item_no9 LIKE '$value' is related with an AND operator to the IN condition.

WHERE (item_no LIKE '$value' or item_no1 LIKE '$value' or
      item_no2 LIKE '$value' or item_no3 LIKE '$value' or
      item_no4 LIKE '$value' or item_no5 LIKE '$value' or 
      item_no6 LIKE '$value' or item_no7 LIKE '$value' or
      item_no8 LIKE '$value' or item_no9 LIKE '$value'
      )

In addition change the IN condition to the following.
You don't want a revision that is not the max revision of of its sheet_ID to match with a max revision of another sheet_ID.

      AND (sheet_ID,revision) IN (SELECT sheet_ID,MAX(revision)
                                  FROM product_sheets
                                  GROUP BY sheet_ID
                                  );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM