Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
T-SQL:查找以前发生过的顺序错误值_Sql_Tsql_Sql Server 2014 - Fatal编程技术网

T-SQL:查找以前发生过的顺序错误值

T-SQL:查找以前发生过的顺序错误值,sql,tsql,sql-server-2014,Sql,Tsql,Sql Server 2014,这个问题与查找无序事件有关,但只查找以前发生过的事件。在下表的机器人移动数据中,每个移动都应按顺序指向相同或更高的点编号,如果为真,则DIR方向=1。正确的序列已预先编程为SeqCorr,实际序列已记录为SeqAct以供比较 Spot Dir SeqCorr SeqAct moveID ------------------------------ 9 1 113 117 1085 9 1 114 118 1086 10 1 115

这个问题与查找无序事件有关,但只查找以前发生过的事件。在下表的机器人移动数据中,每个移动都应按顺序指向相同或更高的点编号,如果为真,则DIR方向=1。正确的序列已预先编程为SeqCorr,实际序列已记录为SeqAct以供比较

Spot Dir SeqCorr SeqAct moveID
------------------------------
 9    1    113    117    1085
 9    1    114    118    1086
 10   1    115    119    1087
 10   1    116    120    1088
 2    0    1      121    1089
 2    1    2      122    1090
 2    1    3      123    1091
 6    1    5      124    1092
 6    1    6      125    1093
 2    0    4      126    1094
 6    1    7      127    1095
 6    1    8      128    1096

问题是如何查询数据,以检测点的Dir=0(如moveID=1094的Spot2)以及该点在moveID 1089到1091之前至少访问过一次的情况

输出将是一个moveID列表和另一个状态列,显示返回到以前访问过的地点的移动

Status moveID
-------------
 0    1085
 0    1086
 0    1087
 0    1088
 0    1089
 0    1090
 0    1091
 0    1092
 0    1093
 1    1094
 0    1095
 0    1096

这将为您提供针对给定id访问过某个地点的所有移动

select m1.*
from moves m1
join moves m2 ON m1.spot = m2.spot and m1.moveID > m2.moveID
where m2.dir = 0
这将为您提供一行中发生的移动

select distinct m1.*
from moves m1
join moves m2 ON m1.spot = m2.spot and m1.dir = m2.dir and m1.moveID > m2.moveID
where m1.dir = 1

我怀疑机器人坐在一个位置上进行相邻动作是可以的。这一问题后来又回到了早些时候的问题上

如果是这样,这就是缺口和孤岛问题的一个例子。这可以通过不同的行号来解决,以在机器人位于给定位置时获得相邻移动:

select spot, min(moveid) as min_moveid, max(moveid) as max_moveid
from (select m.*,
             row_number() over (order by moveid) as seqnum,
             row_number() over (partition by spot order by moveid) as seqnum_s
      from moves m
     ) m
group by (seqnum - seqnum_s), spot;
为什么这样做有点难解释,但很容易理解。如果运行子查询,您将看到行号的差异如何定义每个点

现在,问题是每个点的移动范围——一个点出现不止一次吗。为此,我们现在可以使用count*作为窗口函数。因此,要获取重复移动的出现次数,请执行以下操作:

with s as (
      select spot, min(moveid), max(moveid)
      from (select m.*,
                   row_number() over (order by moveid) as seqnum,
                   row_number() over (partition by spot order by moveid) as seqnum_s
            from moves m
           ) m
      group by (seqnum - seqnum_s), spot
     )
select s.*
from (select s.*,
             count(*) over (partition by spot) as cnt
      from s
     ) s
where cnt > 1;

我相信这回答了你的问题。

这是问题的最终解决方案。这一次,我添加了基于更大数据集的分区和分组,这些数据集涵盖了不同生产线和制造工厂不同部分的机器人

SELECT line, robot, min(moveid) moveIDmin, max(moveid) moveIDmax
        from (select m.*,
                     row_number() over (partition by line, robot order by moveid) as seqnum,
                     row_number() over (partition by line, robot, spot order by moveid) as seqnum_s
              from #Temp2 m
             ) m
        group by line, robot, (seqnum - seqnum_s), spot
        order by line, robot, moveIDmin
由此产生的输出使得低效的移动可以很容易地定位,就像在moveIDmin 298,机器人已经移动回先前访问过的位置

   line  robot spot moveIDmin moveIDmax
  AER389X  G    26       1        72
  AER389X  G    30      73       137
  AER389X  J     2     138       139
  AER389X  J     6     140       224
  AER389X  J    10     225       297
  AER389X  J     6     298       301
  AER389X  J    14     302       319
  AER389X  K    14     320       380
  AER389X  K    18     381       468 

你怎么知道之前和之后发生了什么?在关系数据库中,表是无序的,因此除非您有一个列可以按顺序使用,如创建日期或标识列,否则无法知道记录的前后。此外,样本数据最好作为+。请将您的问题包括在内,包括您当前的尝试和期望的结果。如moveID=1094的Spot2,并且在moveID 1089到1091之前,该Spot至少被访问过一次,您所说的之前发生的事件的所有序列和ID都大于之后发生的事件的序列和ID。你是倒数还是我遗漏了什么?谢谢Zohar,是的,moveID充当了一个标识列。为了更清楚地了解stick bit的要求,移动次数会随着时间的推移而增加,因此在moveID 1094处返回第2点是在最初3次访问第2点后,moveID为1089到1091。推测第6点是另一个例子,但是9和10不是。你应该解释一下这种差异。谢谢你。你能回答一个问题吗minmoveID和maxmoveID应该在哪里使用???@FyllSee。我应该给他们取个别名,但是当一个点被连续占据时,他们会显示移动的范围。这将显示范围的一行,而不是每个移动的单独一行。您可以使用join、exists或in获取原始行,但我发现这种表示方式通常更方便。