我正在尝试进行查询,以便为每个项目组生成前10个项目的列表。 它适用于超市连锁店,所有商品都分为商品组。例如大米,盐等。不同品牌的大米和不同品牌的盐。
我需要从SAP Business One Table(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中使用过数组,所以我如何构建一个查询来获得我想要的东西?任何帮助表示赞赏。
答案 0 :(得分: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
答案 1 :(得分:1)
我用Google搜索了OITM和OITB模式。
我知道您错误地将OITB描述为组和项目实体。
根据我的发现:
因此,扩展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