0

I have data like in this mysql table:

id  customer_id  int_proc   inventory
1   A           1           1   
2   A           4           1
3   A           5           1
4   A           0           2
5   A           5           2
6   A           6           2
7   B           6           1       
8   B           7           1
9   B           9           1
10  B           9           2
11  B           9           2
12  C           22          1

I want to get all data from the latest 2 int_proc values for every inventory and where the customer_id is A and B. My result should be like this:

id  customer_id  int_proc   inventory
2   A           4           1
3   A           5           1
5   A           5           2
6   A           6           2
8   B           7           1
9   B           9           1
10  B           9           2
11  B           9           2

Any help is greatly appreciated.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
cahro88
  • 7
  • 4

2 Answers2

1

You can use Mysql's user defined variables and give a rank to rows per customer and per inventory with in a same customer group,below query will give 2 latest int_proc per inventory and same customer group if you want to get latest n number of records just change where clause to where t2.r <= n

select 
t2.id,
t2.customer_id,
t2.int_proc, 
t2.inventory
from (
select t.*,
@r:= case when @g = t.customer_id
     then
          case when @sg = t.inventory 
          then  @r+1 
          else 1 end 
      else 1 end r,
@g:= t.customer_id g,
@sg:= t.inventory sg
from test t
cross join (select @g:=null,@sg:=null,@r:=null) t1
  where t.customer_id in('A','B')
order by t.customer_id,t.inventory,t.int_proc desc
  ) t2
where t2.r <= 2
order by id

Fiddle Demo

Edit for duplicate values

If you have duplicated rows for the int_proc you have to add another sub case statement to check for repeated values and rank them accordingly

select 
t2.id,
t2.customer_id,
t2.inventory,
t2.int_proc
from (
select t.*,
@r:= case when @g = t.customer_id
     then
          case when @sg = t.inventory 
          then 
            case when @sr <> t.int_proc
            then  @r+1 
            else @r end 
          else 1 end 
      else 1 end r,
@g:= t.customer_id g,
@sg:= t.inventory sg,
@sr:= t.int_proc sr
from test t
cross join (select @g:=null,@sg:=null,@r:=null,@sr:=null) t1
  where t.customer_id in('A','B')
order by t.customer_id,t.inventory,t.int_proc desc
  ) t2
 where t2.r <= 2
order by id

Fiddle Demo 2

M Khalid Junaid
  • 63,861
  • 10
  • 90
  • 118
  • 1
    The question appears to be duplicated. However, I suspect that this is the best performing answer – Strawberry Sep 13 '14 at 13:20
  • Hi, that looks good. Thank you. I just tested it. I included some values for customer_id B, 93,95 and 95 should be shown, however 95 and 95 (2 results) are being returned. How can I return - all data - for the latest 2 (93;95) int_proc? http://www.sqlfiddle.com/#!2/9fee8/1 – cahro88 Sep 13 '14 at 13:29
  • @cahro88 if you have duplicated values see my updated answer – M Khalid Junaid Sep 13 '14 at 13:43
  • 1
    @MKhalidJunaid: Thank you so much. My first tests seem to work properly. You're brilliant! ;) Thanks a ton! – cahro88 Sep 13 '14 at 13:50
  • @cahro88 consider accepting an answer for more help see [*Accepting Answers: How does it work*](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – M Khalid Junaid Sep 13 '14 at 13:52
  • @MKhalidJunaid: This query would also be for a good performance, e.g. when having lots of millions of rows in the table? – cahro88 Sep 13 '14 at 13:52
  • @cahro88 why don't you just give it try on your product server with [*Explain plan*](http://dev.mysql.com/doc/refman/5.0/en/using-explain.html) – M Khalid Junaid Sep 13 '14 at 13:56
  • Its *production server my bad :) – M Khalid Junaid Sep 13 '14 at 19:23
  • @MKhalidJunaid: There are some problems with this solution. Can you have a look the the sqlfiddle I posted below? – cahro88 Sep 29 '14 at 12:40
  • @cahro88 i have fixed [*`See Updated demo`*](http://www.sqlfiddle.com/#!2/e81fdf/10) Also note you have to stick with `order by t.customer_id,t.inventory,t.int_proc desc` other wise you will not get correct result – M Khalid Junaid Sep 29 '14 at 18:49
  • @MKhalidJunaid: Wondeful, thank you so much! I'll try and implement it though ;) Thanks a ton! – cahro88 Sep 30 '14 at 12:06
  • @MKhalidJunaid: Wonderful. This works fine. However, I am confused ;) If I add a date and would like to limit the query by a date or a date range, it won't work properly. Do I miss something here? http://sqlfiddle.com/#!2/db162/11 – cahro88 Oct 27 '14 at 19:39
  • @MKhalidJunaid: Can you take a look at a new post, it turned out that the query is quite slow on large sets. This would really help us! http://stackoverflow.com/questions/30343270/query-efficiency-select-the-2-latest-group-batch-records-from-table?noredirect=1#comment48780295_30343270 – cahro88 May 20 '15 at 09:03
-1

@MKhalidJunaid: your solution worked for quite a while. However, we now get multiple results sets instead of the only two latest int_proc's. Can you please execute the following table at http://www.sqlfiddle.com/#!2/e81fdf/2 (this might be due to the unordered rows of data?)

CREATE TABLE test
    (`id` int, `customer_id` varchar(1), `int_proc` int, `inventory` int)
;

INSERT INTO test
    (`id`, `customer_id`, `int_proc`, `inventory`)
VALUES
    (1, 'A', 1, 1),
    (2, 'A', 4, 1),
    (3, 'A', 5, 1),
    (4, 'A', 0, 1),
    (5, 'A', 5, 1),
    (6, 'A', 6, 1),
    (7, 'A', 6, 1),
    (8, 'A', 7, 1),
    (9, 'A', 9, 1),
    (10, 'B', 91, 2),
    (11, 'B', 92, 2),
    (12, 'B', 93, 2),
    (13, 'B', 95, 2),
    (14, 'B', 95, 2),
    (15, 'C', 22, 1)

;
cahro88
  • 7
  • 4
  • @MKhalidJunaid: I just tested your solution with some "unsorted rows" which will exist in the real database. There are a lot of double results again (the real table has 100k sets now which has a lot of double data sets and therefore performance issues...) Can you have a closer look at this? http://www.sqlfiddle.com/#!2/ddea6 That would be very helpful! – cahro88 Oct 27 '14 at 17:51
  • @MKhalidJunaid: Can you take a look at a new post, it turned out that the query is quite slow on large sets. This would really help us! http://stackoverflow.com/questions/30343270/query-efficiency-select-the-2-latest-group-batch-records-from-table?noredirect=1#comment48780295_30343270 – cahro88 May 20 '15 at 09:03