查找订单中商品的累计发生

时间:2019-04-16 10:37:05

标签: sql sql-server

使用SLQserver 2014,我有一张包含销售(订​​单和商品)的表,其中每条订单出现的文章不超过一次。

销售

public static Xbrl accountingData(string input)
{
        Xbrl xmlDoc = new Xbrl();
        XmlSerializer ser = new XmlSerializer(typeof(Xbrl));

        try
        {
             using (XmlReader reader = XmlReader.Create(input))
             {
                xmlDoc = (Xbrl)ser.Deserialize(reader);
                return xmlDoc;
             }
        }
        catch (Exception e)
        {
            WriteLine($"Error: {e.Message}");
            ReadLine();
            return null;
        }
}

我想知道的是,根据出现最多的订单,按销量最高的商品排序。

按文章出现的时间排序:

ORDER    ARTICLE
----------------
0001          A
0001          B
0001          C
0002          A
0002          C
0003          D
0004          A

一共有4个订单(0001、0002、0003、0004)

预期输出如下:

ARTICLE  COUNT
--------------
A         3
C         2
B         1
D         1

因此,商品A以3个顺序出现,当您添加商品C时,它们以3个顺序出现(商品C的出现顺序与A没什么不同),当您添加商品B时,它们仍然仅以3个顺序出现订单,最后添加文章D,它们以4个不同的顺序出现。

我相信我需要做某种递归查询,但是我在代码中苦苦挣扎。

感谢您的帮助!

3 个答案:

答案 0 :(得分:1)

这很复杂。想法是给每个<div class='parent'> <div class='child'>h</div> <div class='child'>1</div> <div class='child'>2</div> <div class='child'>3</div> </div>分配一个数字,该数字是最终输出中出现的最小“行”。

这比我最初想的要难一些。似乎需要计算结果集,将信息应用于订单,然后重新汇总:

order

Here是db <>小提琴。

答案 1 :(得分:1)

您可以使用相关子查询来查找排名低于某个文章的所有文章(基于计数和名称)并执行不同的计数:

DECLARE @t TABLE([order] VARCHAR(10), article VARCHAR(10));
INSERT INTO @t VALUES
('0001', 'A'),
('0001', 'B'),
('0001', 'C'),
('0002', 'A'),
('0002', 'C'),
('0003', 'D'),
('0004', 'A');

WITH cte AS (
    SELECT article, ROW_NUMBER() OVER (ORDER BY COUNT(*) DESC, article) AS rn
    FROM @t
    GROUP BY article
)
SELECT *, (
    SELECT COUNT(DISTINCT [order])
    FROM @t
    WHERE article IN (
        SELECT article
        FROM cte AS x
        WHERE rn <= cte.rn
    )
) AS running_order_count
FROM cte
ORDER BY rn

答案 2 :(得分:0)

with 
--  sample data
SALES as
(
    select  [ORDER] = '0001', [ARTICLE] = 'A' union all
    select  [ORDER] = '0001', [ARTICLE] = 'B' union all
    select  [ORDER] = '0001', [ARTICLE] = 'C' union all
    select  [ORDER] = '0002', [ARTICLE] = 'A' union all
    select  [ORDER] = '0002', [ARTICLE] = 'C' union all
    select  [ORDER] = '0003', [ARTICLE] = 'D' union all
    select  [ORDER] = '0004', [ARTICLE] = 'A'
),
--  find count by article + assign a row number
cte as
(
    select  [ARTICLE], [COUNT] = count(*), RN = row_number() over (order by count(*) desc, [ARTICLE])
    from    SALES s
    group by [ARTICLE]
)
select  *
from    cte c
        cross apply
        (
            -- for each row find the distinct [ORDER] for current [ARTICLE]
            -- including all earlier row. Based on `RN`
            select  CUMULATIVE_ORDER_COUNT  = count(distinct [ORDER])
            from    cte x
                    inner join SALES s  on  x.ARTICLE   = s.ARTICLE
            where   x.RN    <= c.RN
        ) cc
order by c.[COUNT] desc, c.[ARTICLE]

/*  RESULT

ARTICLE COUNT   RN  CUMULATIVE_ORDER_COUNT
A       3       1   3
C       2       2   3
B       1       3   3
D       1       4   4

*/