【问题标题】:sql with max and several joins具有最大和多个连接的 sql
【发布时间】:2018-08-16 02:21:44
【问题描述】:

我正在尝试获取每个客户在 mysql 上为每种产品支付的最后价格。 以下 sql 没有给我正确的数据。 max(dateLasFullfillment) 并没有太多的行值,它甚至不是最大的 vsalue。这就像 max 之前的 group by 作品。

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

以下是一些具有预期结果的表格示例。 sql 必须以 select 语句开头,除非没有其他选项,否则不能声明等。

SO 表:

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 表:

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

产品表:

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

计量表:

id  code
11  cs10
12  cs20
13  cs30

CUSTOMER 表:

ID  NAME
1  CUSTOMER1#
2  CUSTOMER2#
3  CUSTOMER3#

预期结果:

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

【问题讨论】:

  • 这将有助于显示一些示例输入数据以及预期的输出。仅根据查询,我无法猜测您要做什么。
  • 我有一个 SO(销售订单)表和 SOITEM(每个销售订单中的项目),我正在尝试查找每个客户为每个项目 (sku) 支付的最新价格。例如 SO 表有:id、customerId、dateCompleted 和 SOItem 有 soid、productnum、unitprice、dateLastFulfillment。 so 中的 id 与 soitem 中的 soid 匹配。分组是按客户 ID 和产品编号。这些表很大,所以我需要一些时间来生成一些示例数据。问题是 soitem 有价格但没有 customerid,因此我不能在那里分组。
  • 该描述对您的问题没有多大帮助。最好向我们展示数据,因为这样我们就可以看到正在发生的事情。此外,您可能希望通过删除其中一些连接来简化查询,如果它们不是获得答案所必需的。
  • ...当您添加该信息时,请通过edit提出您的问题,而不是添加评论。
  • 好的,我编辑了问题并添加了表格。我花了一些时间来获取正确的数据。谢谢。我还澄清说我使用的是 mysql,除非没有其他选项,否则语句应以 select 为星标。

标签: mysql sql join group-by max


【解决方案1】:

试试这个,只是代码的第一部分,看看你会得到什么。然后粘贴到您的其他联接等中(删除前两个旧 where 项目,以及所有分组依据)

-- 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

【讨论】:

  • 谢谢。我应该提到我正在使用 mysql,此时我正在通过一个应用程序运行 sqls,该应用程序允许我通过其接口连接其数据库,并且我只能运行只读选择。查询必须以 select 开头。没有声明等。但会看看我是否可以通过一些 sql 客户端连接数据库。与此同时,我正要添加一些示例表格。
  • @shnick 然后在你的问题中添加MySQL标签!!!这是在浪费大家的时间。他/她创建查询需要时间,对您来说毫无用处,因为他/她给您查询到错误的 dbms。
  • 如果唯一的问题是声明/打印,那么您可以在代码中创建@now_minus_6mos 并将其作为参数传递吗?在我的 sqlserver 上重现问题确实需要时间。请立即将 MySQL 标签添加到您的问题中!!
  • 添加了标签,不幸的是我无法将声明添加到代码中。
【解决方案2】:

您可以使用“排名”功能来做到这一点。它们在 MySQL 中不存在,但您可以模仿它们。

查看这篇文章。

Rank function in MySQL

【讨论】:

    猜你喜欢
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    相关资源
    最近更新 更多