将多个订单行合并为每个订单1行,最多5个

时间:2018-11-20 15:27:00

标签: sql sql-server tsql

使用SQL Server 2016

问题:我从网络订单系统收到一个平面文件。我需要将此数据导入我们的内部邮件订购系统。网络订单文件每个项目的每个订单包含1行。因此,如果订购了12个商品,那么将有12个具有相同订购ID的行。我需要对此进行转换,以便订单项位于同一行。需要注意的是,每个订单每行最多只能有5个订单项。因此,订购的12件物品需要变成3行。在第1行和第2行的末尾,需要有一个继续标记,说明顺序在下一行继续。

网络订单文件示例:

Web Order Sample

SAMPLE# Row orderid ocustomerid odate   ofirstname  customer_pmntprofileid itemid   numitems    unitprice   itemamount
1   1   171476  5230    11/14/2018  Scott   1324426745  R22046  1   269.95  269.95
1   2   171476  5230    11/14/2018  Scott   1324426745  R81100  12  7.5 90
3   1   171690  6119    11/14/2018  Joe 1382758196  AF49972 6   39.95   239.7
3   2   171690  6119    11/14/2018  Joe 1382758196  AF49973 4   39.95   159.8
3   3   171690  6119    11/14/2018  Joe 1382758196  AF47970 1   43.95   43.95
3   4   171690  6119    11/14/2018  Joe 1382758196  AF44090 1   43.95   43.95
3   5   171690  6119    11/14/2018  Joe 1382758196  AF44091 1   43.95   43.95
3   6   171690  6119    11/14/2018  Joe 1382758196  AF44092 1   43.95   43.95
3   7   171690  6119    11/14/2018  Joe 1382758196  AF44093 1   43.95   43.95
3   8   171690  6119    11/14/2018  Joe 1382758196  AF44094 1   43.95   43.95
3   9   171690  6119    11/14/2018  Joe 1382758196  AF44114 1   50.95   50.95
3   10  171690  6119    11/14/2018  Joe 1382758196  AF44139 1   46.95   46.95
3   11  171690  6119    11/14/2018  Joe 1382758196  AF44138 1   46.95   46.95
3   12  171690  6119    11/14/2018  Joe 1382758196  AF44066 1   43.95   43.95
4   1   171702  6120    11/14/2018  Tim 1382791806  L81313  5   17.95   89.75
4   2   171702  6120    11/14/2018  Tim 1382791806  L81314  1   30.95   30.95
4   3   171702  6120    11/14/2018  Tim 1382791806  L82039  6   8.95    53.7
4   4   171702  6120    11/14/2018  Tim 1382791806  L82013  1   69.95   69.95

我需要将样本1变成1行,将样本3变成3行,并将样本4变成1行。 需要的输出:

Order Import Sample

SAMPLE #    orderid ocustomerid odate   ofirstname  customer_pmntprofileid  ITEM_ID1    QTY1    PRICE1  AMOUNT1 ITEM_ID2    QTY2    PRICE2  AMOUNT2 ITEM_ID3    QTY3    PRICE3  AMOUNT3 ITEM_ID4    QTY4    PRICE4  AMOUNT4 ITEM_ID5    QTY5    PRICE5  AMOUNT5 Continue
1   171476  5230    11/14/2018  Scott   1324426745  R22046  1   269.95  269.95  R81100  12  7.5 90                                                  N
3   171690  6119    11/14/2018  Joe 1382758196  AF49972 6   39.95   239.7   AF49973 4   39.95   159.8   AF47970 1   43.95   43.95   AF44090 1   43.95   43.95   AF44091 1   43.95   43.95   Y
3   171690  6119    11/14/2018  Joe 1382758196  AF44092 1   43.95   43.95   AF44093 1   43.95   43.95   AF44094 1   43.95   43.95   AF44114 1   50.95   50.95   AF44139 1   46.95   46.95   Y
3   171690  6119    11/14/2018  Joe 1382758196  AF44138 1   46.95   46.95   AF44066 1   43.95   43.95                                                   N
4   171702  6120    11/14/2018  Tim 1382791806  L81313  5   17.95   89.75   L81314  1   30.95   30.95   L82039  6   8.95    53.7    L82013  1   69.95   69.95                   N
5   171706  70  11/14/2018  Bruce   1382821080  L84264  1   584.99  584.99  L84409  1   584.99  584.99  L84410  1   584.99  584.99  L84633  1   539.99  539.99  L84634  1   539.99  539.99  Y

2 个答案:

答案 0 :(得分:0)

您可以通过条件聚合来做到这一点:

select SAMPLE, orderid, ocustomerid, odate, ofirstname, customer_pmntprofileid,
       max(case when seqnum % 5 = 1 then itemid end) as itemid_1,
       max(case when seqnum % 5 = 1 then numitems end) as numitems_1,
       max(case when seqnum % 5 = 1 then unitprice end) as unitprice_1,
       max(case when seqnum % 5 = 1 then itemamount end) as itemamount_1,  
       max(case when seqnum % 5 = 2 then itemid end) as itemid_2,
       max(case when seqnum % 5 = 2 then numitems end) as numitems_2,
       max(case when seqnum % 5 = 2 then unitprice end) as unitprice_2,
       max(case when seqnum % 5 = 2 then itemamount end) as itemamount_2,  
       max(case when seqnum % 5 = 3 then itemid end) as itemid_1,
       max(case when seqnum % 5 = 3 then numitems end) as numitems_1,
       max(case when seqnum % 5 = 3 then unitprice end) as unitprice_1,
       max(case when seqnum % 5 = 3 then itemamount end) as itemamount_1,  
       max(case when seqnum % 5 = 4 then itemid end) as itemid_4,
       max(case when seqnum % 5 = 4 then numitems end) as numitems_4,
       max(case when seqnum % 5 = 4 then unitprice end) as unitprice_4,
       max(case when seqnum % 5 = 4 then itemamount end) as itemamount_4,  
       max(case when seqnum % 5 = 0 then itemid end) as itemid_5,
       max(case when seqnum % 5 = 0 then numitems end) as numitems_5,
       max(case when seqnum % 5 = 0 then unitprice end) as unitprice_5,
       max(case when seqnum % 5 = 0 then itemamount end) as itemamount_5,
       (case when max(seqnum) < max(cnt) then 'Y' else 'N' end) as continuation_flag 
from (select wo.*,
             row_number() over (partition by orderid order by row) as seqnum,
             row_number() over (partition by orderid) as cnt
      from web_orders wo
     ) wo
group by SAMPLE, orderid, ocustomerid, odate, ofirstname, customer_pmntprofileid,
         (seqnum - 1) / 5;

答案 1 :(得分:0)

您可以这样做:

WITH 
t1 AS (select * FROM mytable WHERE row % 5 = 1),
t2 AS (select * FROM mytable WHERE row % 5 = 2),
t3 AS (select * FROM mytable WHERE row % 5 = 3),
t4 AS (select * FROM mytable WHERE row % 5 = 4),
t5 AS (select * FROM mytable WHERE row % 5 = 0)
SELECT t1.SAMPLE,
       ceiling(t1.Row/5.0) AS Row,
       t1.orderid,
       t1.ocustomerid,
       t1.odate,
       t1.ofirstname,
       t1.customer_pmntprofileid,
       t1.itemid AS itemid1,
       t1.numitems AS numitems1,
       t1.unitprice AS unitprice1,
       t1.itemamount AS itemAmount1,
       t2.itemid AS itemId2,
       t2.numitems AS numitems2,
       t2.unitprice AS unitprice2,
       t2.itemamount AS itemamount2,
       t3.itemid AS itemId3,
       t3.numitems AS numitems3,
       t3.unitprice AS unitprice3,
       t3.itemamount AS itemamount3,
       t4.itemid AS itemId4,
       t4.numitems AS numitems4,
       t4.unitprice AS unitprice4,
       t4.itemamount AS itemamount4,
       t5.itemid AS itemId5,
       t5.numitems AS numitems5,
       t5.unitprice AS unitprice5,
       t5.itemamount AS itemamount5
FROM t1
LEFT JOIN t2 ON t1.orderid = t2.orderid AND CEILING(t1.row/5.0)=ceiling(t2.row/5.0)
LEFT JOIN t3 ON t1.orderid = t3.orderid AND CEILING(t1.row/5.0)=ceiling(t3.row/5.0)
LEFT JOIN t4 ON t1.orderid = t4.orderid AND CEILING(t1.row/5.0)=ceiling(t4.row/5.0)
LEFT JOIN t5 ON t1.orderid = t5.orderid AND CEILING(t1.row/5.0)=ceiling(t5.row/5.0);

DBFiddle demo