SQL将类似的值组合在一起

时间:2012-03-30 08:42:11

标签: sql sql-server-2008

我遇到分组数据的问题。我一直使用group by子句,但这次我想将类似的有价数据组合在一起。 我需要一些与序列号相关的工作。如果我可以将具有或多或少相同序列号的作业组合在一起,那么我可以运行较少数量的作业。

我的数据是这样的。

    JobID         Sequence
    A01            8               
    A01            6
    A01            10 
    A02            5
    A02            10
    A02            4
    A02            2
    A03            8
    A03            3
    A03            6
    A03            10
    A04            5
    A04            4
    A04            2
    A04            9
    A04            10

从以上数据可以看出,A02和A04有更多共同点,A01和A03有更多共同点。

应该采取什么样的查询来将类似的数据组放在一起,如下所示将A02和A04组合在一起,将A01和A03组合在一起,序列列上的顺序并不重要。

    JobID         Sequence
    A01            8               
    A01            6
    A01            10 
    A03            8
    A03            3
    A03            6
    A03            10
    A02            5
    A02            10
    A02            4
    A02            2
    A04            5
    A04            4
    A04            2
    A04            9
    A04            10

感谢您的时间

大卫

PS - 更多解释。

在上面的列表JobID中 A01包含序列(8,6,10) A02包含序列(5,10,4,2) A03包含序列(8,3,6,10) A04含有序列(5,4,2,9,10)

因此,作业A01和作业A03具有相似的序列号,作业A02和作业A03具有相似的序列号。我想根据类似的序列号对它们进行分组 还有许多其他作业的序列可能与其他作业的序列号相匹配。我只是包含了4个工作来保持名单的小。

3 个答案:

答案 0 :(得分:2)

这是一个更复杂的问题然后我觉得现在一直在思考,但我会给你一个想法开始,也许别人可以帮助你完成它...

像这样加入桌子:

Select  A.JobID, A.Sequence, Count(*) 

from    TheTable A join
        TheTable B on A.JobID <> B.JobID and A.Sequence = B.Sequence

group by A.JobID

我没有测试过,所以可能会有拼写错误,但你希望得到这个想法。请注意,您正在加入作业不同的地方,但顺序是。

答案 1 :(得分:2)

从其他答案中推断......可能会有所帮助。

在这里,每两个工作人员都有类似的情况:

http://sqlfiddle.com/#!3/c28be/9

Create table Data(Job nvarchar(10), seq int);

insert into data
SELECT 'A01' ,8  UNION ALL
SELECT 'A01',6 UNION ALL
SELECT 'A01',10 UNION ALL
SELECT 'A02',5 UNION ALL
SELECT 'A02',10 UNION ALL
SELECT 'A02',4 UNION ALL
SELECT 'A02',2 UNION ALL
SELECT 'A03',8 UNION ALL
SELECT 'A03',3 UNION ALL
SELECT 'A03',6 UNION ALL
SELECT 'A03',10 UNION ALL
SELECT 'A04',5 UNION ALL
SELECT 'A04',4 UNION ALL
SELECT 'A04',2 UNION ALL
SELECT 'A04',9 UNION ALL
SELECT 'A04',10;


select 
  d1.job as j1, 
  d2.job as j2, 
  count(*) cnt 
from Data d1 inner join Data d2 on (d1.seq = d2.seq and d1.job < d2.job)
group by d1.job, d2.job
;

答案 2 :(得分:1)

以Brandon Moores为基础回答:

数据设置:

DECLARE @Data TABLE (JobId nvarchar(10), Sequence int)
INSERT INTO @Data(JobId, Sequence)
SELECT 'A01',8 UNION ALL
SELECT 'A01',6 UNION ALL
SELECT 'A01',10 UNION ALL
SELECT 'A02',5 UNION ALL
SELECT 'A02',10 UNION ALL
SELECT 'A02',4 UNION ALL
SELECT 'A02',2 UNION ALL
SELECT 'A03',8 UNION ALL
SELECT 'A03',3 UNION ALL
SELECT 'A03',6 UNION ALL
SELECT 'A03',10 UNION ALL
SELECT 'A04',5 UNION ALL
SELECT 'A04',4 UNION ALL
SELECT 'A04',2 UNION ALL
SELECT 'A04',9 UNION ALL
SELECT 'A04',10 UNION ALL
SELECT 'A05',100 

查找每个JobID共有的所有序列的总数,按顺序排列最多,从每个JobId输出所有数据,具体取决于该顺序:

;WITH cte AS (
    SELECT  A.JobID, A.Sequence, Count(*) AS [SequencesInCommon]
    FROM    @Data A 
    LEFT OUTER JOIN
        @Data B on A.JobID <> B.JobID and A.Sequence = B.Sequence
    GROUP BY A.JobID, A.Sequence
),    
cte2 AS (
    SELECT JobID, SUM(SequencesInCommon) AS Total 
    FROM cte
    GROUP BY JobID
)    
SELECT  d.JobId, d.Sequence
FROM    cte2 c
INNER JOIN @Data d on c.jobID = d.JobID
ORDER BY c.Total ASC, c.JobID ASC

给出:

JobId      Sequence
---------- -----------
A05        100
A01        8
A01        6
A01        10
A03        8
A03        3
A03        6
A03        10
A02        5
A02        10
A02        4
A02        2
A04        5
A04        4
A04        2
A04        9
A04        10

(17 row(s) affected)

应该这样做:)