我有一张这样的表:
Product sl_no Wt_Kg
Prod-001 1 3.000
Prod-002 2 4.000
Prod-003 3 2.000
Prod-004 4 3.000
Prod-005 5 6.000
Prod-006 6 7.000
Prod-007 7 1.000
Prod-008 8 2.000
Prod-009 9 3.000
Prod-010 10 5.000
Prod-011 11 2.000
Prod-012 12 4.000
我需要此表中的所有记录从序列号开始,直到达到指定的重量总和(kgs)。
例如,如果我想从序列号(Sl_no)1获得权重小于或等于25千克的所有产品,我应该得到以下结果:
Product sl_no Wt_Kg
Prod-001 1 3.000
Prod-002 2 4.000
Prod-003 3 2.000
Prod-004 4 3.000
Prod-005 5 6.000
Prod-006 6 7.000
在下一个例子中,如果我希望所有产品都从序列号3开始,重量小于或等于30kgs,我应该得到以下结果:
Product sl_no Wt_Kg
Prod-003 3 2.000
Prod-004 4 3.000
Prod-005 5 6.000
Prod-006 6 7.000
Prod-007 7 1.000
Prod-008 8 2.000
Prod-009 9 3.000
Prod-010 10 5.000
请帮助我实现这一目标。提前谢谢......
答案 0 :(得分:3)
这可能更有效率。我首先在我的数据库中创建一个名为_test的表,与您的描述相匹配。此解决方案利用了在UPDATE
语句(http://haacked.com/archive/2004/02/28/sql-auto-increment.aspx)中递增值的功能。达到目标值后停止递增。如果您拥有数百万种产品,性能将成为一个问题,但您可以假设您将在一定数量的产品中达到目标重量(基于平均重量)并使用SET ROW_COUNT
来限制最初的记录数量表变量。
DECLARE @Weight REAL
DECLARE @SerialNumber INT
DECLARE @MaxWeight REAL
SET @Weight = 0
SET @SerialNumber = 3
SET @MaxWeight = 30
DECLARE @Results TABLE
(
Product CHAR(8),
sl_no INT,
Wt_Kg REAL,
Total_Wt REAL
)
INSERT INTO
@Results
(
Product,
sl_no,
Wt_KG
)
SELECT
Product,
sl_no,
Wt_KG
FROM
_test
WHERE
sl_no >= @SerialNumber
ORDER BY
sl_no
UPDATE
@Results
SET
@Weight = Total_Wt = Wt_Kg + @Weight
WHERE
@Weight <= @MaxWeight
SELECT
*
FROM
@Results
WHERE
Total_Wt <= @MaxWeight
结果是:
Product sl_no Wt_Kg Total_Wt
-------- ----------- ------------- -------------
Prod-003 3 2 2
Prod-004 4 3 5
Prod-005 5 6 11
Prod-006 6 7 18
Prod-007 7 1 19
Prod-008 8 2 21
Prod-009 9 3 24
Prod-010 10 5 29
答案 1 :(得分:1)
declare @total decimal(9,3), @sl_no int
select @total = 25.000, @sl_no = 0 -- first case
--select @total = 30.000, @sl_no = 3 -- second case
;with tab (Product, sl_no, Wt_Kg) as (
select 'Prod-001', 1, 3.000 union all
select 'Prod-002', 2, 4.000 union all
select 'Prod-003', 3, 2.000 union all
select 'Prod-004', 4, 3.000 union all
select 'Prod-005', 5, 6.000 union all
select 'Prod-006', 6, 7.000 union all
select 'Prod-007', 7, 1.000 union all
select 'Prod-008', 8, 2.000 union all
select 'Prod-009', 9, 3.000 union all
select 'Prod-010', 10, 5.000 union all
select 'Prod-011', 11, 2.000 union all
select 'Prod-012', 12, 4.000
)
select t3.*
from tab t3
join (
select t1.product, t1.sl_no, sum(t2.Wt_Kg) as total
from tab t1
join tab t2 on t1.sl_no >= t2.sl_no
where t2.sl_no >= @sl_no
group by t1.product, t1.sl_no
) t on t.product = t3.product and t.sl_no = t3.sl_no
where t.total <= @total
已添加:按sl_no
分组和加入(仅在product
不唯一的情况下)
结果是,第一种情况:
Product sl_no Wt_Kg
Prod-001 1 3.000
Prod-002 2 4.000
Prod-003 3 2.000
Prod-004 4 3.000
Prod-005 5 6.000
Prod-006 6 7.000
第二种情况:
Product sl_no Wt_Kg
Prod-003 3 2.000
Prod-004 4 3.000
Prod-005 5 6.000
Prod-006 6 7.000
Prod-007 7 1.000
Prod-008 8 2.000
Prod-009 9 3.000
Prod-010 10 5.000
答案 2 :(得分:1)
我的解决方案:
declare @total decimal(9,3), @sl_no int
select @total = 25.000, @sl_no = 1 -- first case
select * from Tab where sl_no<=
(
select MAX(sl_no3) from (
select t3.sl_no sl_no3, sum(t3.Wt_kg) Wt_kg3 from (
select t1.sl_no sl_no, t2.Wt_Kg as Wt_kg from Tab t1, Tab t2 where t1.sl_no>=t2.sl_no and t2.sl_no >=@sl_no
) t3 group by t3.sl_no having SUM(t3.Wt_kg) <= @total
) t4
) and sl_no>=$sl_no
答案 3 :(得分:0)
如果序列号是唯一的:
第一个例子:
select *
from tableName
where sl_no >= 1
and Wt_Kg <= 25
第二个例子:
select *
from tableName
where sl_no >= 3
and Wt_Kg <= 30
如果序列号不唯一:
select Product, sl_no, Sum(Wt_Kg)
from tableName
where Wt_Kg <= 25
group by Product, sl_no
修改强>:
如果您想按总和值过滤结果,可以试试这个:
select Product, sl_no, Sum(Wt_Kg)
from tableName
group by Product, sl_no
having (Sum(Wt_Kg) <= 25)
请记住,如果Product OR sl_no是唯一的而不是Sum()没有意义,那么聚合将用于共享特定值的记录。