Question

I'm working directly with a Magento DB, trying to get a list of all orders with an order status of Shipped, excluding those paid for via wire transfer (bankpayment). Here's my current query:

SELECT * FROM (
  SELECT 
    so.entity_id, 
    so.created_at, 
    MAX(soe.created_at) AS shipped_at 
  FROM sales_order so 
  LEFT OUTER JOIN sales_order_entity soe 
    ON (soe.parent_id=so.entity_id) 
  LEFT OUTER JOIN sales_order_entity_varchar soev 
    ON (soev.entity_id = soe.entity_id) 
    AND (soev.value <> 'bankpayment') 
  WHERE (soev.value = 'shipped') 
  GROUP BY so.entity_id) AS shipped 
WHERE (shipped.shipped_at >= '2013-05-01 04:00:00') 
AND (shipped.shipped_at <= '2013-05-02 03:59:59');

I'm not really a SQL expert, and you can see where I'm trying to select orders not paid for by wire transfer with this line:

AND (soev.value <> 'bankpayment')

But it doesn't work as expected, and I suspect that it has to do with the WHERE clause:

WHERE (soev.value = 'shipped')

I don't know how to properly write this query. Any advice?

NOTE - In this case, I'm not able to use Magento models/collections for gathering the data.

Was it helpful?

Solution

You are looking for entities that have 'shipped' but not 'bankpayment'. You want to look for these values on different rows. In other words, you want to accept an entity that has a row with 'shipped' but only when there are no rows with 'bankpayment'.

You can do this logic in the having clause. Well, you don't quite have a having clause. You have a subquery with a where clause on the outside. Although this is equivalent, I'm simplifying the query to eliminate the subquery. Then, I'm using the having clause to check the dates and the presence/absence of the two values:

SELECT so.entity_id, so.created_at, 
       MAX(soe.created_at) AS shipped_at 
FROM sales_order so LEFT OUTER JOIN
     sales_order_entity soe 
     ON soe.parent_id = so.entity_id LEFT OUTER JOIN
     sales_order_entity_varchar soev 
     ON soev.entity_id = soe.entity_id
GROUP BY so.entity_id
having MAX(soe.created_at) >= '2013-05-01 04:00:00' AND 
       MAX(soe.created_at) <= '2013-05-02 03:59:59' and
       SUM(soev.value = 'shipped') > 0 and
       sum(soev.value = 'bankpayment') = 0;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top