Question

Here is a screenshot of the SQL command results:

enter image description here

Here is the SQL command:

SELECT inl_cbsubs_subscriptions.user_id AS cbsubsUserID, inl_cbsubs_subscriptions.id AS cbsubsId, inl_cbsubs_subscriptions.status AS status, inl_cbsubs_payment_items.subscription_id     AS paymentSubID, inl_cbsubs_payment_items.stop_date AS paymentStopDate, inl_cbsubs_payment_items.id AS paymentID
FROM inl_cbsubs_subscriptions
INNER JOIN inl_cbsubs_payment_items
ON inl_cbsubs_subscriptions.id=inl_cbsubs_payment_items.subscription_id
WHERE status='C'
ORDER BY paymentID DESC;

I am looking to adjust this command so that I have only the most recent result showing on a per user basis. So in other words, this is what the table should resemble in this case:

enter image description here

As you can see, the cbsubsUserID only shows one result per ID whereas before there were multiple results for the 596 id.

Was it helpful?

Solution

If you want the most recent result, the best way to do it is with not exists:

SELECT s.user_id AS cbsubsUserID, s.id AS cbsubsId, s.status AS status,
       i.subscription_id AS paymentSubID, i.stop_date AS paymentStopDate, i.id AS paymentID
FROM inl_cbsubs_subscriptions s INNER JOIN
     inl_cbsubs_payment_items i
     ON s.id = i.subscription_id
WHERE s.status = 'C' and
      not exists (select 1
                  from inl_cbsubs_payment_items i2
                  where i2.subscription_id = i.subscription_id and
                    i2.id > i.id
                 )
ORDER BY paymentID DESC;

You will want an index on inl_cbsubs_payment_items(subscription_id, paymentid).

What this is saying is: "Get me all the items for a given subscription id that have no bigger payment stop dates for that subscription". It is a fancy way of saying "get me the most recent for each subscription id", but it tends to work best in the database.

OTHER TIPS

I think you can use GROUP BY to achieve this

SELECT inl_cbsubs_subscriptions.user_id AS cbsubsUserID, inl_cbsubs_subscriptions.id AS cbsubsId, inl_cbsubs_subscriptions.status AS status, inl_cbsubs_payment_items.subscription_id     AS paymentSubID, inl_cbsubs_payment_items.stop_date AS paymentStopDate, inl_cbsubs_payment_items.id AS paymentID
FROM inl_cbsubs_subscriptions
INNER JOIN inl_cbsubs_payment_items
ON inl_cbsubs_subscriptions.id=inl_cbsubs_payment_items.subscription_id
WHERE status='C'
GROUP BY inl_cbsubs_subscriptions.user_id
ORDER BY paymentID DESC;
SELECT inl_cbsubs_subscriptions.user_id AS cbsubsUserID, MAX(inl_cbsubs_subscriptions.id) AS cbsubsId, inl_cbsubs_subscriptions.status AS status, MAX(inl_cbsubs_payment_items.subscription_id)     AS paymentSubID, x.stop_date AS paymentStopDate, x.blah AS paymentID
FROM inl_cbsubs_subscriptions
INNER JOIN inl_cbsubs_payment_items
ON inl_cbsubs_subscriptions.id=inl_cbsubs_payment_items.subscription_id
INNER JOIN
(SELECT inl_cbsubs_payment_items.stop_date as stop_date ,
 MAX(inl_cbsubs_payment_items.id) as blah
 FROM inl_cbsubs_subscriptions
 INNER JOIN inl_cbsubs_payment_items
 ON inl_cbsubs_subscriptions.id=inl_cbsubs_payment_items.subscription_id
 WHERE status='C'
 GROUP BY inl_cbsubs_subscriptions.user_id)as x
ON x.stop_date=inl_cbsubs_payment_items.stop_date AND x.blah=inl_cbsubs_payment_items.id
WHERE status='C'
GROUP BY inl_cbsubs_subscriptions.user_id
ORDER BY paymentID DESC;

To get the most recent record per group you can do so

SELECT DISTINCT
s.user_id AS cbsubsUserID, 
s.id AS cbsubsId, 
s.status AS `status`, 
si.subscription_id     AS paymentSubID,
si.stop_date AS paymentStopDate, 
si.id AS paymentID
FROM inl_cbsubs_subscriptions s
INNER JOIN inl_cbsubs_payment_items si
ON s.id=si.subscription_id
 INNER JOIN (SELECT MAX(stop_date) stop_date ,subscription_id ,MAX(id) id
FROM inl_cbsubs_payment_items 
GROUP BY subscription_id ) max_si
ON 
(max_si.subscription_id=si.subscription_id 
AND max_si.id =si.id 
AND  max_si.stop_date = si.stop_date )
WHERE `status`='C'
ORDER BY paymentID DESC;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top