按模糊标准分组

时间:2011-04-13 18:30:02

标签: sql group-by

有没有办法在SQL中执行此任务:

有一个行李名称及其权重表,如下所示

 luggage_id | luggage_name | luggage_weight   
------------+--------------+----------------  
          1 | Tom          |              2  
          2 | Kat          |              3  
          3 | Lil          |              4  

输出重量不同于D单位或不足D单位的东西。因此,如果D等于1,我们必须得到

1. Tom, Kat
2. Kat, Lil

如果D等于2,我们必须得到

1. Tom, Kat, Lil

如果D为0.5,我们得到

1. Tom
2. Kat
3. Lil

我尝试使用交叉联接:

SELECT t1.luggage_name, t2.luggage_name
FROM Luggages t1, Luggages t2
WHERE ABS(t1.luggage_weight - t2.luggage_weight) <= 1

导致


 luggage_name | luggage_name 
--------------+--------------
 Tom          | Tom
 Tom          | Kat
 Kat          | Tom
 Kat          | Kat
 Kat          | Lil
 Lil          | Kat
 Lil          | Lil

是否可以使用SQL解决此问题?

EDIT 好的,是的,我们可以写

SELECT t1.luggage_name, t2.luggage_name
FROM Luggages t1, Luggages t2
WHERE ABS(t1.luggage_weight - t2.luggage_weight) <= 1
      AND t1.luggage_id < t2.luggage_id

然后我们会得到

 luggage_name | luggage_name 
--------------+--------------
 Tom          | Kat
 Kat          | Lil

这意味着Tom与Kat和Kat在一起组成了Lil。

但是,假设我们拥有所有相同权重的表


 luggage_id | luggage_name | luggage_weight 
------------+--------------+----------------
          1 | Tom          |              1
          2 | Kat          |              1
          3 | Lil          |              1

然后我们会得到


 luggage_name | luggage_name 
--------------+--------------
 Tom          | Kat
 Tom          | Lil
 Kat          | Lil

这意味着Tom和Kat和Lil一样是正确的,但是下一组,Kat和Lil已经在第一组了。我想到了这个问题,无法弄清楚如何解决它。如何仅输出不同的组?

2 个答案:

答案 0 :(得分:3)

您需要一个条件将完整的笛卡尔坐标限制为三角形连接

SELECT t1.luggage_name, t2.luggage_name
FROM Luggages t1, Luggages t2
WHERE ABS(t1.luggage_weight - t2.luggage_weight) <= 1

AND
t1.luggageid < t2.luggageid

删除不需要的对

修改

您的输出将是

 luggage_name | luggage_name 
--------------+--------------
 Tom          | Kat
 Kat          | Lil

d=0.5时,你有没有对,因为没有小于0.5的差异。与d <= 1

的输出相比,单身人士列表实际上是错误

编辑2:证明那些你没有得到它的人......

DECLARE @luggage TABLE (luggageid int IDENTITY(1,1), luggage_name varchar(30), luggage_weight float)
INSERT @luggage (luggage_name, luggage_weight) VALUES ('Tom', 2), ('Kat', 3), ('Lil', 4)

SELECT t1.luggage_name, t2.luggage_name
FROM @luggage t1, @luggage t2
WHERE ABS(t1.luggage_weight - t2.luggage_weight) <= 1
AND
t1.luggageid < t2.luggageid


SELECT t1.luggage_name, t2.luggage_name
FROM @luggage t1, @luggage t2
WHERE ABS(t1.luggage_weight - t2.luggage_weight) <= 2
AND
t1.luggageid < t2.luggageid


SELECT t1.luggage_name, t2.luggage_name
FROM @luggage t1, @luggage t2
WHERE ABS(t1.luggage_weight - t2.luggage_weight) <= 0.5
AND
t1.luggageid < t2.luggageid

答案 1 :(得分:1)

SELECT t1.luggage_name, MIN(t2.luggage_name) GroupsWith
FROM Luggages t1
JOIN Luggages t2 ON ABS(t1.luggage_weight - t2.luggage_weight) <= 1
AND ((t1.luggage_weight < t2.luggage_weight)
  OR (t1.luggage_weight = t2.luggage_weight AND t1.luggage_name < t2.luggage_name))
GROUP BY t1.luggage_name
ORDER BY t1.luggage_name

这将显示一组没有重复的分组用户,所以如果你有

Tom-2, Kat-3, Lil-4, Bob-5

他们彼此都是D = 1。如果您的查询的D = 1,则会显示

Kat Lil
Lil Bob
Tom Kat

显示整个群组Tom-&gt; Kat-&gt; Lil-&gt; Bob。