T-SQL中的首选序列算法

时间:2017-01-25 12:27:07

标签: sql sql-server algorithm tsql sequence

说明

我正在使用SQL Server 2012.我需要编写算法来根据设置时间决定生产产品的顺序。

我的意思是:例如,我们需要生产4种产品:A B C D

我有一个矩阵(表Changeover),其中包含每个产品的设置时间,如下所示:

Xasis   Yasis   Time
--------------------
A       B       10
A       C       15
A       D       5
B       A       5
B       C       20
B       D       10
C       A       10
C       B       15
C       D       5
D       A       0
D       B       5
D       C       25

规则:

  • 如果我们首先生产产品A,并且在我们生产产品B之后,将会有10分钟的设置时间......

  • 如果我们首先生产产品A,并且在我们生产产品C之后,将会有15分钟的设置时间......

  • 如果我们首先生产产品B,并且在我们生产产品A之后,将会有5分钟的设置时间......

依旧......

期望的输出:

目标是制作产品序列最短的时间。因此,使用此示例数据将是:

   5       0       10      (Total 15 minutes)
C ----> D ----> A ----> B

此输出不正确:

   15      10      0       (Total 25 minutes)
C ----> B ----> D ----> A

我有另一张表格Products,其中包含以下数据:

Product    Rank
A          1
B          2
C          3
D          4

Products中的排名值表示生产产品的顺序,因此使用此示例序列将是:

   10      20      5       (Total 35 minutes)
A ----> B ----> C ----> D

所以它不正确,因为总设置时间是35分钟。

期望的结果:我需要算法来更新Products表,如:

Product    Rank
A          3
B          4
C          1
D          2

   5       0       10      (Total 15 minutes)
C ----> D ----> A ----> B

你有什么想法可以做到这一点吗? (实际上有超过140种产品)

示例数据:

CREATE TABLE #Attr
(
    Id NVARCHAR(20),
    [Rank] INT
)

INSERT INTO #Attr (Id, [Rank]) 
VALUES ('A',1), ('B',2), ('C',3), ('D',4)

CREATE TABLE #Change
(
    Xasis NVARCHAR(20),
    Yasis NVARCHAR(20),
    [Time] INT
)

INSERT INTO #Change (Xasis, Yasis, [Time]) 
VALUES ('A','B',10), ('A','C',15), ('A','D',5),
       ('B','A',5), ('B','C',20), ('B','D',10),
       ('C','A',10), ('C','B',15), ('C','D',5),
       ('D','A',0), ('D','B',5), ('D','C',25);

我尝试过:我可以获得以下每组最低的设置时间:

WITH filtered AS
(
    SELECT 
        *, 
        ROW_NUMBER() OVER(PARTITION BY Xasis ORDER BY [Time]) AS RankPerGroup
    FROM #Change AS c
)
SELECT 
    *, ROW_NUMBER() OVER(ORDER BY [Time]) AS [Rank]
FROM filtered f1
WHERE RankPerGroup = 1

我得到了以下输出:

Xasis   Yasis   Time    RankPerGroup    Rank
D       A       0       1               1
A       D       5       1               2
B       A       5       1               3
C       D       5       1               4

这是不正确的,因为我不能按顺序产生:

    0       D already produced, so that's incorrect
D ----> A --X--> D ---

希望我解释清楚,如果您有任何问题或误解我,请问我,我会提供更多信息。

1 个答案:

答案 0 :(得分:1)

如果您有四种产品,您可以这样做:

join

这是在SQL中实现强力算法。通常,这是使用单个查询可以做到的最佳效果。

not in确保序列成为可能。 $_file = @fopen($filePath, "r"); $isComplete = feof($_file); fclose($file); 保证链中的新链接不会返回到以前的产品。

如果您有更多产品,您可以自定义查询您拥有的产品数量。或者,您可以设置递归子查询。但是,我会小心的。当你获得10种产品时,这可能会变得非常昂贵。

对于一个大问题,您可能希望使用图形数据库或高级分析软件来查看其他类型的优化算法(可能是近似的)。