Domanda

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.

È stato utile?

Soluzione

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.

Altri suggerimenti

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top