3

我有如下表(产品)

id  name      quality  weight
1   Demir-1   ST-1     10
2   Demir-2   ST-2      7
3   Demir-3   ST-1     20
4   Demir-2   ST-3      8
5   Demir-1   ST-3      6
6   Demir-4   ST-2     10
7   Demir-2   ST-2     12
8   Demir-1   ST-1     15
9   Demir-1   ST-3     10
10  Demir-3   ST-3      5
11  Demir-2   ST-2      5

现在,如果用户想要获取重量总和在 20 到 25 之间且 name='Result-2' 的产品列表,则结果应如下所示。重量总和在 20 到 25 之间时,必须显示所有组合。

 id name      quality  weight    
  4 Demir-2   ST-3      8   
  7 Demir-2   ST-2     12   
 11 Demir-2  ST-2       5
------------------------------
  2 Demir-2   ST-2      7
  4 Demir-2   ST-3      8
 11 Demir-2   ST-2      5
------------------------------ 
------------------------------ 
  1 Demir-1   ST-1     10
  8 Demir-1   ST-1     15

您可以看到总和(重量)为 25。

4

5 回答 5

4
DECLARE @tblProducts TABLE(Id INT IDENTITY, ProductName varchar(50),Quality varchar(50), ProductWeight int)
INSERT INTO @tblProducts SELECT 'Demir-1','ST-1',10
INSERT INTO @tblProducts SELECT 'Demir-2','ST-2',7
INSERT INTO @tblProducts SELECT 'Demir-3','ST-1',20
INSERT INTO @tblProducts SELECT 'Demir-2','ST-3',8
INSERT INTO @tblProducts SELECT  'Demir-1','ST-3',6
INSERT INTO @tblProducts SELECT  'Demir-4','ST-2',10
INSERT INTO @tblProducts SELECT 'Demir-2','ST-2' ,12
INSERT INTO @tblProducts SELECT  'Demir-1','ST-1',15
INSERT INTO @tblProducts SELECT  'Demir-1','ST-3',10
INSERT INTO @tblProducts SELECT 'Demir-3','ST-3' ,5
INSERT INTO @tblProducts SELECT 'Demir-2' ,'ST-2 ',5

 ;WITH Cte (Id,ProductQuality,ProductIds,ProductNames,ProductQualities,ProductTotalWeight,ProductWeights,ProductName1,ProductName2) AS
(
    SELECT  Id
            ,Quality            
            , ',' + CAST(Id AS VARCHAR(MAX))  
            ,',' + CAST(ProductName AS VARCHAR(MAX))
            ,',' + CAST(Quality AS VARCHAR(MAX)) 
            ,ProductWeight
            , ',' + CAST(ProductWeight AS VARCHAR(MAX)) 
            ,ProductName
            ,CAST(ProductName AS VARCHAR(MAX))
    FROM @tblProducts
    UNION ALL
    SELECT p.Id
            , p.Quality            
            ,c.ProductIds + ',' +  CAST(p.Id AS VARCHAR(MAX))
            ,c.ProductNames + ',' +  CAST(p.ProductName AS VARCHAR(MAX)) 
             ,c.ProductQualities + ',' + CAST(p.Quality AS VARCHAR(MAX)) 
             ,c.ProductTotalWeight + p.ProductWeight          
            ,c.ProductWeights + ',' + CAST(p.ProductWeight AS VARCHAR(MAX))
            ,p.ProductName
            ,c.ProductName2
    FROM @tblProducts AS p JOIN Cte c ON p.Id < c.Id
    WHERE  p.ProductName = c.ProductName2
    )
SELECT 
        ProductIds = STUFF(ProductIds,1,1,'')
        ,ProductNames = STUFF(ProductNames,1,1,'')
        ,ProductQualities = STUFF(ProductQualities,1,1,'')
        ,ProductTotalWeight
        ,ProductWeights = STUFF(ProductWeights,1,1,'')
FROM CTE 
WHERE ProductTotalWeight BETWEEN 20 AND 25

结果

ProductIds  ProductNames             ProductQualities   ProductTotalWeight  ProductWeights
3           Demir-3                 ST-1                20                  20
11,7,2      Demir-2,Demir-2,Demir-2 ST-2 ,ST-2,ST-2     24                  5,12,7
11,7,4      Demir-2,Demir-2,Demir-2 ST-2 ,ST-2,ST-3     25                  5,12,8
11,4,2      Demir-2,Demir-2,Demir-2 ST-2 ,ST-3,ST-2     20                  5,8,7
10,3        Demir-3,Demir-3         ST-3,ST-1           25                  5,20
9,1         Demir-1,Demir-1         ST-3,ST-1           20                 10,10
9,8         Demir-1,Demir-1         ST-3,ST-1           25                 10,15
8,1         Demir-1,Demir-1         ST-1,ST-1           25                 15,10
8,5         Demir-1,Demir-1         ST-1,ST-3           21                  15,6
7,4         Demir-2,Demir-2         ST-2,ST-3           20                  12,8
于 2012-09-12T09:29:27.070 回答
2

不幸的是,SQL 并不是正确的编码引擎,无法从具有给定计算的表中得出所有组合,正如我一起破解的 SQL 代码所示。

通常我会建议这是用程序语言编码的,因为它的性质。另请注意,此处的解决方案使用较大的输入数据集可以快速耗尽 SQL 的递归限制。可能的产品数量也可以增长到足够大,以至于运行速度非常缓慢。

drop table products
drop table #MinW
drop table #Products
go
create table products
(
id  int,
name  varchar(20),  
quality varchar(20),
[weight] int
) 
go
insert into products
select
1,   'Demir-1',   'ST-1',     10 
union
select 2,   'Demir-2',   'ST-2',      7 
union
select 3,   'Demir-3',   'ST-1',     20 
union
select 4,   'Demir-2',   'ST-3',      8 
union
select 5,   'Demir-1',   'ST-3',      6 
union
select 6,   'Demir-4',   'ST-2',     10 
union
select 7,   'Demir-2',   'ST-2',     12 
union
select 8,   'Demir-1',   'ST-1',     15 
union
select 9,   'Demir-1',   'ST-3',     10 
union
select 10,  'Demir-3',   'ST-3',      5 
union
select 11,  'Demir-2',   'ST-2',      5 
go
select 
p.id, p.name, p.quality, p.weight
into #MinW
from products p
inner join
(
select name,min(weight) as weight
from products group by name having min(weight) < 25
) as minW
on p.name = minW.name and p.weight = minW.weight

go
with weightProducts (id, name, [weight],history)
as
( 
select id, name,[weight],convert(varchar(1024),'"'+convert(varchar(10),id)+'",') from #minW
union all
select products.id, products.name,products.[weight] + weightProducts.[weight],convert(varchar(1024),weightProducts.history+'"'+convert(varchar(10),products.id)+'",') from products, weightProducts where products.name = weightproducts.name and  charindex('"'+convert(varchar(10),products.id)+'",',weightProducts.history)<=0 and (products.weight + weightProducts.weight) < 25
)
-- Statement using the CTE
select *
into #Products
from weightProducts
where weight between 20 and 25

go

select 
p1.history,
p2.id,
p2.quality,
p2.weight,
p1.weight as totalWeight
from #Products p1
inner join
products p2 on p1.name = p2.name and charindex('"'+convert(varchar(10),p2.id)+'",',p1.history)>0
order by 
p1.history,
p2.id 
于 2012-09-12T09:20:17.100 回答
0
SELECT * FROM tablename
WHERE name IN (
 SELECT name FROM tablename 
 GROUP BY name
 HAVING SUM(weight) BETWEEN 20 AND 25)
于 2012-09-12T06:23:11.190 回答
0

这个查询怎么样:

select id, name, quality, weight from PRODUCTS
group by id, name, quality, weight
having sum(weight) between 20 and 25
于 2012-09-12T06:24:09.187 回答
0

尝试这个:

SELECT * FROM products
WHERE name IN (
              SELECT name FROM products
              GROUP BY name
              HAVING SUM(weight) BETWEEN 20 AND 25)
于 2012-09-12T06:25:42.507 回答