Mysql 需要帮助将数据集从多行转换为单行吗

Mysql 需要帮助将数据集从多行转换为单行吗,mysql,sql,database,Mysql,Sql,Database,我有一个数据库MySQL,它保存了我们一些客户的成本记录。每个客户的商品成本不同。任何给定的成本记录都有一个生效日期范围,即成本在给定的时间范围内有效。以下是一些示例数据: Customer ItemNumber EffectDate Counter Cost ABC123 ITEM101 2011-12-01 0 $1.00 ABC123 ITEM101 2011-12-10 0

我有一个数据库MySQL,它保存了我们一些客户的成本记录。每个客户的商品成本不同。任何给定的成本记录都有一个生效日期范围,即成本在给定的时间范围内有效。以下是一些示例数据:

Customer    ItemNumber    EffectDate    Counter    Cost
ABC123      ITEM101       2011-12-01          0    $1.00
ABC123      ITEM101       2011-12-10          0    $1.20
ABC123      ITEM101       2011-12-10          1    $1.25
DEF456      ITEM101       2011-11-15          0    $1.10
DEF456      ITEM101       2011-12-01          0    $1.12
为了让这些数据有一定的意义,反变量是它被更改的次数。这是来自过时的会计平台,日期是成本的开始日期。因此,客户ABC123的项目101在2011年1月12日和2011年8月12日的成本将为1.00美元,但从2011年10月12日开始,成本将为1.25美元,将为1.20美元,但计数器已上升-即现在的成本为1.25美元。我希望这是有道理的

我想做的是得到如下数据:

Customer    ItemNumber    EffectiveBegin    EffectiveEnd    Cost
ABC123      ITEM101       2011-12-01        2011-12-09      $1.00
ABC123      ITEM101       2011-12-10        2099-12-31      $1.25
DEF456      ITEM101       2011-11-15        2011-11-30      $1.10
DEF456      ITEM101       2011-12-01        2099-12-31      $1.12
其中,2099年12月31日只是当前日期的占位符日期


任何帮助都将不胜感激

未测试:读作:我可能至少有一个逻辑错误和2-3个语法错误

Areas where there might be problems:

    1) B.effectiveDate-1 - Hoping B.EffectDate-1 when B.EffectDate is null 
       will retrun null so coalesce will return 12/31/2099.
    2) '12/31/2099' may need to be cast to date data type.
    3) Hoping mySQL supports date-1 to subtract 1 day.
    4) Replace "TABLE" with your table name
它的作用是:

1) Joins to self in order to get begin & End for Effective dates. Excludes same
   date entries.
2) subtracts 1 from B.effectdate when customer item has multiple entries to 
   get "End"
3) Only joins records where customer, item match AND B.Counter is the MAX counter. 
   (Key if multiple entires)
4) Uses cost from B if exists, otherwise uses A.
不言而喻:

    Select A.Customer, A.ItemNumber, A.EffectDate as EffectiveBegin, 
            coalesce(B.effectDate-1,'12/31/2099') as EffectiveEnd, 
            coalesce(B.cost, A.cost) as Cost
    FROM Table A
    LEFT JOIN Table B 
      ON A.Customer=B.Customer 
     and A.ItemNumber = B.ItemNumber 
     and A.EffectDate < B.EffectDate
     and B.Counter = (SELECT max(C.Counter) 
                      FROM Table C 
                      WHERE C.Customer = A.customer 
                        and C.ItemNumber = A.ItemNumber)

基本概述:给我成本和日期-1最高的柜台附属B记录。如果没有b记录,使用记录信息作为成本,使用12/31/2099作为结束日期。

未测试:读作:我可能至少有一个逻辑错误和2-3个语法错误

Areas where there might be problems:

    1) B.effectiveDate-1 - Hoping B.EffectDate-1 when B.EffectDate is null 
       will retrun null so coalesce will return 12/31/2099.
    2) '12/31/2099' may need to be cast to date data type.
    3) Hoping mySQL supports date-1 to subtract 1 day.
    4) Replace "TABLE" with your table name
它的作用是:

1) Joins to self in order to get begin & End for Effective dates. Excludes same
   date entries.
2) subtracts 1 from B.effectdate when customer item has multiple entries to 
   get "End"
3) Only joins records where customer, item match AND B.Counter is the MAX counter. 
   (Key if multiple entires)
4) Uses cost from B if exists, otherwise uses A.
不言而喻:

    Select A.Customer, A.ItemNumber, A.EffectDate as EffectiveBegin, 
            coalesce(B.effectDate-1,'12/31/2099') as EffectiveEnd, 
            coalesce(B.cost, A.cost) as Cost
    FROM Table A
    LEFT JOIN Table B 
      ON A.Customer=B.Customer 
     and A.ItemNumber = B.ItemNumber 
     and A.EffectDate < B.EffectDate
     and B.Counter = (SELECT max(C.Counter) 
                      FROM Table C 
                      WHERE C.Customer = A.customer 
                        and C.ItemNumber = A.ItemNumber)

基本概述:给我成本和日期-1最高的柜台附属B记录。如果没有b记录,则使用记录信息作为成本,使用12/31/2099作为结束日期。

我测试了@xQbert提出的查询,但它返回了5行样本数据,而不是您要求的4行

下面是一个测试查询,它为您的测试数据返回四行:

select p.Customer, p.ItemNumber, p.EffectDate, coalesce(e.effectdate - interval 1 day, curdate()) EffectiveEnd, p.Cost
from (
  select customer, itemnumber, effectdate, max(counter) counter
  from prices
  group by customer, itemnumber, effectdate
) c
left outer join prices p
  on p.customer = c.customer 
  and p.itemnumber = c.itemnumber 
  and p.effectdate = c.effectdate
  and p.counter = c.counter
left outer join prices e
  on e.customer = p.customer 
  and e.itemnumber = p.itemnumber 
  and e.effectdate > p.effectdate
  and e.counter = p.counter

我测试了@xQbert提出的查询,但它返回5行样本数据,而不是您要求的4行

下面是一个测试查询,它为您的测试数据返回四行:

select p.Customer, p.ItemNumber, p.EffectDate, coalesce(e.effectdate - interval 1 day, curdate()) EffectiveEnd, p.Cost
from (
  select customer, itemnumber, effectdate, max(counter) counter
  from prices
  group by customer, itemnumber, effectdate
) c
left outer join prices p
  on p.customer = c.customer 
  and p.itemnumber = c.itemnumber 
  and p.effectdate = c.effectdate
  and p.counter = c.counter
left outer join prices e
  on e.customer = p.customer 
  and e.itemnumber = p.itemnumber 
  and e.effectdate > p.effectdate
  and e.counter = p.counter

计数器是否与您尝试构建的查询相关?你似乎只关心日期范围,对吧?计数器是相关的,因为给定开始日期,我只需要与该日期最高计数器相关的成本。例如,10月12日ABC123的ITEM101有两条记录-计数器0,成本为1.20美元;1号柜台的价格是1.25美元。我只需要花费1.25美元。计数器是否与您试图构建的查询相关?你似乎只关心日期范围,对吧?计数器是相关的,因为给定开始日期,我只需要与该日期最高计数器相关的成本。例如,10月12日ABC123的ITEM101有两条记录-计数器0,成本为1.20美元;1号柜台的价格是1.25美元。我只需要花1美元。25@thomasbosonix指出我遗漏了一些东西你确定你有想要的结果吗?或者离得足够近,你就能得到你想要的东西?@thomas bosonix指出我遗漏了一些东西你确定你得到了你想要的结果吗?或者离得足够近你就能得到你想要的?