Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I don't believe this statement is true:</p> <blockquote> <p>The original problem lies in the fact that the sub query cannot see the tables you joined to in the main query. So p.product_id and p2c.product_id do not exist in the sub query.</p> </blockquote> <p>Since that condition is part of an outer join in the main query, that condition is already known to be true or will evaluate to null and thereby cause a null result. Now your sample data suggests you don't need outer joins anyway and I can see that there are expiration dates into the future on many of the rows.</p> <p>I believe you meant to write this as your subquery. It might be worth a try even though some of the other info we've got suggests it still won't quite be the final solution.</p> <pre><code>( SELECT MIN(date_expires) FROM product as p2 WHERE date_expires &gt;= NOW() AND p2.product_id = p.product_id ) AS expiring </code></pre> <p><strong>EDIT</strong> Make the change I just suggested, but also get rid of the GROUP BY clause.</p> <p><strong>EDIT 2</strong></p> <p><strong>1)</strong> You seem to have attributes in multiple tables that might belong in a single product table. I'll assume that you have good reasons for that.</p> <p><strong>2)</strong> Mysql allows you to mix aggregate and non-aggregate columns, but that is a bad practice and if my theory proves true, that was a big part of the reason we were all stumped for a little while.</p> <p><strong>3)</strong> All of the left outer joins seem be doing what you'd normally use an inner join for. You won't regret doing this right the first time.</p> <p><strong>4)</strong> The expiration date can be looked up via a subquery the way you first wrote it or as another join as done by the other answer. If there is really a one-to-one relationship there, then MIN() and GROUP BY are not necessary and may confuse somebody. (In fact, see edit #3.)</p> <p><strong>5)</strong> Since your subquery evaluates as null for any product with an expiration falling in the past, you may need to ORDER BY a second column or just use the expiration date regardless of whether it's past or future.</p> <p><strong>EDIT 3</strong></p> <pre><code>SELECT c.category_id, MIN(name) as name, c.image /* better as a subquery if you can't do an aggregate on a LOB */ MIN(c.description) as description, /* don't even need the subquery because you've already joined the product table */ CASE WHEN MIN(p.date_expires) &gt;= NOW() THEN MIN(p.date_expires) ELSE NULL /* this may not be what you really wanted */ END as expiring_my_first_guess, /* what was really intended */ MIN( CASE WHEN p.date_expires &gt;= NOW() THEN p.date_expires ELSE NULL END ) as expiring, FROM category c INNER JOIN category_description cd ON (c.category_id = cd.category_id) INNER JOIN product_to_category p2c ON (c.category_id = p2c.category_id) INNER JOIN JOIN product p ON (p2c.product_id = p.product_id) WHERE c.parent_id = 0 AND c.status = '1' GROUP BY c.category_id ORDER BY expiring </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload