0

I am trying to get the last prices each customer paid for each product on mysql. the following sql is not giving me the right data. the max(dateLasFullfillment) doesn't much the row value and its not even the max vsalue. its like the group by works before the max.

select 
    'item' AS type, soitem.productnum as 'SKU',
    (soitem.unitprice / right(uom.code, length(uom.code) - 2)) as unitPrice, 
    replace(customer.name, "#", "") AS priceList, 
    max(soitem.dateLastFulfillment) 
from 
    soitem
left join 
    so ON so.id = soitem.soid
left join
    customer on so.customerid = customer.id
left join 
    product on product.num = soitem.productnum
left join  
    uom on product.uomid = uom.id
where 
    soitem.dateLastFulfillment > now() - interval 6 month 
    and soitem.unitprice > 0 
    and so.statusid in (20, 25, 60)
group by 
    soitem.productnum, customer.name
order by 
    PriceList

Here are some Tables samples with expected results. the sql must start with select statement, no declare etc unless there is no other option.

SO Table:

id  billToName  customerid  dateCompleted  dateCreated  dateIssued  num
1  Name1  1  6/27/18  6/23/18  6/23/18  ordernum1
2  Name1  1  7/15/18  7/10/18  7/10/18  ordernum2
3  Name1  1  7/29/18  7/20/18  7/20/18  ordernum3
4  Name2  2  6/31/2018  6/30/18  6/30/18  ordernum4
5  Name2  2  7/27/18  7/26/18  7/26/18  ordernum5
6  Name3  3  8/8/18  8/5/18  8/5/18  ordernum6
7  Name3  3  7/25/18  7/20/18  7/20/18  ordernum7

SOITEM table:

id  soId  unitPrice  dateLastFulfillment  productId  productNum  statusId  uomId  qtyOrdered
1  1  10  6/27/18  1  SKU-1  50  11  3
2  1  20  6/27/18  2  SKU-2  50  12  5
3  1  30  6/27/18  3  SKU-3  50  13  6
4  2  11  7/15/18  1  SKU-1  50  11  11
5  2  21  7/15/18  2  SKU-2  50  12  44
6  2  31  7/15/18  3  SKU-3  50  13  5
7  3  12  7/29/18  1  SKU-1  50  11  5
8  3  22  7/29/18  2  SKU-2  50  12  6
9  4  23  6/31/2018  2  SKU-2  50  12  9
10  4  33  6/31/2018  3  SKU-3  50  13  12
11  5  24  7/27/18  2  SKU-2  50  12  14
12  5  34  7/27/18  3  SKU-3  50  13  35
13  6  25  8/8/18  2  SKU-2  50  12  22
14  6  35  8/8/18  3  SKU-3  50  13  55
15  7  26  7/25/18  2  SKU-2  50  12  22
16  7  36  7/25/18  3  SKU-3  50  13  11

PRODUCT table:

num  uomid
SKU-1  11
SKU-2  12
SKU-3  13

UOM table:

id  code
11  cs10
12  cs20
13  cs30

CUSTOMER table:

ID  NAME
1  CUSTOMER1#
2  CUSTOMER2#
3  CUSTOMER3#

EXPECTED RESULTS:

type  SKU  unitPrice  priceList  max(soitem.dateLastFulfillment)
item  SKU-1  1.2  customer1  7/29/18
item  SKU-2  1.1  customer1  7/29/18
item  SKU-3  1.03  customer1  7/15/18
item  SKU-2  1.2  customer2  7/27/18
item  SKU-3  1.13  customer2  7/27/18
item  SKU-2  1.25  customer3  8/8/18
item  SKU-3  1.17  customer3  8/8/18
Cœur
  • 37,241
  • 25
  • 195
  • 267
shnick
  • 1
  • 1
  • 5
    It would help to show some sample input data along with the expected output. I can't guess what you are trying to do based just on the query. – Tim Biegeleisen Aug 16 '18 at 02:26
  • I have a SO (Sales Order) table and SOITEM (items in each sales order) and I am trying to find whats the latest price each customer paid for each item (sku). for example SO table has: id, customerId, dateCompleted and SOItem has soid, productnum,unitprice,dateLastFulfillment . the id in so matches the soid in soitem. the grouping is by customerid and product num. the tables are big so it will take me some time to generate some sample data. the problem is the soitem has the price but doesnt have the customerid and therefore I cannot group there. – shnick Aug 16 '18 at 03:00
  • That description does not add much to your question. Showing us data would be best, because then we can see what is going on. Also, you may want to simplify the query by removing some of those joins, if they are not necessary to get your answer. – Tim Biegeleisen Aug 16 '18 at 03:02
  • ... and when you add that information, please do it by [edit]ing your question, not by adding a comment. – Richardissimo Aug 16 '18 at 05:45
  • ok I edited the question and added tables. took me some time to get the right data. thanks. I also clarified that I am using mysql and the stetement should star with select unless there is no other option. – shnick Aug 16 '18 at 16:49

2 Answers2

0

Try this, just the first part of your code, and see what you get. Then paste in your other Joins etc. (removing first two old where items, and all of the group by)

-- compute this once, instead of for each row
Declare @now_minus_6mos as date = DATEADD(month, -6, GETDATE());
print @now_minus_6mos;

select 
    'item' AS type, soitem.productnum as 'SKU',
    (soitem.unitprice / 1 ) as unitPrice,   -- I do not have UOM, so simplify to be one
    -- I do not have Customer    replace(customer.name, "#", "") AS priceList, 
    (soitem.dateLastFulfillment) -- remove the max, since we are getting only the last one
from 
    (Select * From
        (Select
            productnum
            ,unitprice
            ,dateLastFulfillment
            ,Row_Number() Over(Partition By productnum  Order By dateLastFulfillment DESC) as dlfRow
         From soitem
         --move where filters here to reduce number of rows returned
         Where
             soitem.dateLastFulfillment > @now_minus_6mos 
         and soitem.unitprice > 0 
         ) aa
     Where dlfRow = 1
     ) soitem
donPablo
  • 1,937
  • 1
  • 13
  • 18
  • thank you. I should have mentioned that I am using mysql and at this point I am running the sqls through an app that lets me connect its DB via its interface and I can run only read only selects. the query must start with select. no Declare etc. BUT will look whether I can connect the DB via some sql client. meantime I am just about to add some sample Tables. – shnick Aug 16 '18 at 16:27
  • @shnick Then add `MySQL` tag to your question!!! It's a waste of everybody's time. It takes time for him/her to create a query, and useless for you because he/she give you query to the wrong dbms. – Eric Aug 16 '18 at 17:00
  • If the only problem is the Declare/Print, then can you create the @now_minus_6mos in your code and pass it in as a parameter? It does take time to reproduce the problem on my sqlserver. Please add MySQL tag to your question, right now!! – donPablo Aug 16 '18 at 17:11
  • Added the tag and unfortunately I cannot add the declare to code. – shnick Aug 16 '18 at 17:14
0

You can do this with "ranking" function. They doesn't exists in MySQL but you can imitate them.

See this post.

Rank function in MySQL

DanB
  • 2,022
  • 1
  • 12
  • 24