1

我正在尝试进行查询,从而可以为每个项目组的前 10 个项目生成一个列表。它适用于连锁超市,其中所有物品都分为物品组。例如大米、盐等。会有不同品牌的大米和不同品牌的盐。

我需要从 SAP Business One 表(MS SQL Server 2008)中获取数据

来自项目组表 OITB 的示例结果

SELECT * FROM OITB(显示项目组的前两列)

ItmsGrpCod  ItmsGrpNam
101         RICE
102         SALT
103         SUGAR
104         FROZEN VEGETABLE

这将返回 224 个结果。

SELECT * FROM OITB(显示项目的前两列)

ItemCode    ItemName          ItmsGrpCod    
2001        A1 GRAIN RICE     101
2001        ASHA BRAND RICE   101
2003        PISHORI RICE      101
2004        B7 GRADE RICE     101
2019        JIM SALT          102
2020        KAYKAY SALT       102

我在下面也有这个查询,它获取前 10 个项目,但我必须指定项目组代码(字段 ItmsGrpCod)

SELECT TOP 100 T0.ItemCode, T0.ItemName, T1.DocDate, T6.Price AS COST,P3.Price AS POS,
((P3.Price-T6.Price)/T6.Price)*100 AS [Markup %], T2.OnHand, SUM(T1.Quantity) 
AS Quantity, SUM(T1.LineTotal) AS SALES,T6.Price *SUM(T1.Quantity) AS [Sales 
Cost],SUM(T1.LineTotal) - T6.Price *SUM(T1.Quantity) AS [GP Amount],
(SUM(T1.LineTotal) - T6.Price *SUM(T1.Quantity))/(T6.Price *SUM(T1.Quantity))
*100 as [GP %],T3.WhsName FROM OITM T0
INNER JOIN INV1 T1 ON T0.ItemCode = T1.ItemCode 
INNER JOIN OITW T2 ON T0.ItemCode = T2.ItemCode 
INNER JOIN OWHS T3 ON T1.WhsCode = T3.WhsCode 
INNER JOIN OINV T4 ON T1.DocEntry = T4.DocEntry 
INNER JOIN OITB T5 ON T0.ItmsGrpCod = T5.ItmsGrpCod 
INNER JOIN ITM1 T6 ON T0.ItemCode = T6.ItemCode  
INNER JOIN (SELECT P1.ItemCode, P2.Price FROM OITM P1 
INNER JOIN ITM1 P2 ON P1.ItemCode=P2.ItemCode WHERE 
P2.PriceList='1') P3 ON P3.ItemCode=T0.ItemCode WHERE T6.PriceList ='2' 
AND T2.WhsCode = '01' AND T1.WhsCode = '01' AND T4.DocDate 
= CONVERT(VARCHAR, GETDATE() -1, 101)
AND T0.ItmsGrpCod = '103'  --(Item Group Code)
GROUP BY T0.ItemCode, T0.ItmsGrpCod, T0.ItemName, T1.DocDate, T6.Price, P3.Price, ((P3.Price-T6.Price)
/NULLIF(T6.Price, 0))* 100, T2.OnHand, T3.WhsName ORDER BY Quantity DESC

我需要的是一个查询,它首先从 OITB 获取所有项目组代码并将它们临时存储在一个数组中,然后为每个项目组代码运行第二个查询。假设每个项目组中至少有 10 个项目,查询应该返回 2240 个结果。但是,某些项目组的项目少于 10 个。我真的没有在 SQl 中使用过数组,所以我将如何构建一个查询来获得我想要的东西?任何帮助表示赞赏。

4

2 回答 2

4

我认为这个声明会有所帮助:

Create table OITB (itmsGrpCod int ,ItmsGrpNam varchar(30) )

insert into OITB select 101,'RICE'
insert into OITB select 102,'SALT'
insert into OITB select 103,'SUGAR'
insert into OITB select 104,'FROZEN VEGETABLE'



Create table Item (ItemCode int ,ItemName varchar(20),ItmsGrpCod int )

insert into Item select 1011,'A RICE',101
insert into Item select 1012,'B RICE',101
insert into Item select 1013,'C RICE',101
insert into Item select 1014,'D RICE',101
insert into Item select 1015,'E RICE',101
insert into Item select 1016,'F RICE',101
insert into Item select 1017,'G RICE',101
insert into Item select 1018,'H RICE',101
insert into Item select 1019,'I RICE',101
insert into Item select 10111,'J RICE',101
insert into Item select 10112,'K RICE',101
insert into Item select 10113,'L RICE',101
insert into Item select 10114,'M RICE',101
insert into Item select 1020,'A SALT',102
insert into Item select 1021,'B SALT',102
insert into Item select 1042,'C SALT',102





WITH recordsList
AS
(
    SELECT  Item.*,
            ROW_NUMBER() OVER (PARTITION BY ItmsGrpNam
                                ORDER BY Item.itmsGrpCod ) rn
    FROM    OITB
  inner join 
  Item on OITB.ItmsGrpCod=Item.ItmsGrpCod
)
SELECT  *
FROM    recordsList
WHERE   rn <= 10
于 2013-01-28T07:11:35.257 回答
1

我搜索了 OITM 和 OITB 模式。

我了解到您错误地将 OITB 描述为组和项目实体。

根据我的发现:

  • OITB - 产品组
  • OITM - 产品项目
  • INV1 - 库存

因此,扩展 Ravi 的解决方案,这应该可以解决问题:

WITH OITB_OITM AS
(
  SELECT
    OITB.ItmsGrpCod, OITB.ItmsGrpNam,
    OITM.ItemCode, OITM.ItemName,
    INV1.Quantity,
    ROW_NUMBER() OVER
    (
      PARTITION BY OITB.ItmsGrpNam
      ORDER BY
        INV1.Quantity DESC,
        OITM.ItemName /* For clashing quantities */
    ) idx
  FROM
    OITM
      INNER JOIN INV1 ON INV1.ItemCode   = OITM.ItemCode
      INNER JOIN OITB ON OITB.ItmsGrpCod = OITM.ItmsGrpCod
)
SELECT *
FROM OITB_OITM
WHERE idx <= 10
于 2013-02-02T07:36:27.940 回答