Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.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
Sql 如何按特定顺序选择(几乎)唯一的值_Sql_Distinct - Fatal编程技术网

Sql 如何按特定顺序选择(几乎)唯一的值

Sql 如何按特定顺序选择(几乎)唯一的值,sql,distinct,Sql,Distinct,行程中有几个站点,一个站点=一个地址,其中一个或多个订单按特定顺序加载或交付。 例如: Trip A Trip_order Action Place Ordernumber 10 Load Paris 394798 20 Load Milan 657748 30 UnLoad Athens 657748 40 Unloa

行程中有几个站点,一个站点=一个地址,其中一个或多个订单按特定顺序加载或交付。 例如:

Trip A
Trip_order   Action   Place          Ordernumber
10           Load     Paris          394798
20           Load     Milan          657748
30           UnLoad   Athens         657748
40           Unload   Thessaloniki   394798
50           Load     Thessaloniki   10142
60           Load     Thessaloniki   6577
70           Unload   Athens         6577
80           Unload   Athens         10412
90           Load     Thessaloniki   975147
100          Unload   Paris          975147
我想看看具体的站点,按照行程的顺序:

Load Paris
Load Milan
Unload Athens
Unload Thessaloniki
Load Thessaloniki
Unload Athens
Load Thessaloniki
Unload Paris
我确实看过,但如果我这么做了,我只会得到一次卸载雅典、卸载塞萨洛尼基和装载塞萨洛尼基的机会

我如何解决这个问题

编辑:UTC 11:11+01:00 更具体地说:这些表格提供了这些信息:

Trips
Trip_ID
100001  
100002
100003
....

Actions
Trip_ID  Action MatNr RoOr RoVlg    OrderID
100001   1      10      10     1     394798
100001   1      10      20     1     657748
100001   1      10      30     1     657748
100001   1      10      40     1     394798
100001   1      10      50     1      10142
100001   1      10      60     1       6577
100001   1      10      70     1       6577
100001   1      10      80     1      10412
100001   1      10      90     1     975147
100001   1      10     100     1     975147
操作:1=加载,4=卸载 MatNr、RoOr和RoVlg的组合是行程的顺序

Orders
OrderID LoadingPlace UnloadingPlace
6577    Thessaloniki Athens
10142   Thessaloniki Athens
394798  Paris        Thessaloniki
657748  Milan        Athens
975147  Thessaloniki Paris
试试这个:

将在MySQL中工作:


您不需要也不希望使用distinct来实现这一点,因为我们可以在您的示例中看到多个目的地多次出现。所需内容:筛选出在操作和位置方面与前一条记录匹配的记录

这可能看起来像这样:

SELECT *
FROM Trips t1 LEFT JOIN Trips t2 ON t1.Trip_Order = t2.Trip_Order - 10
WHERE t1.Action <> t2.Action OR t1.Place <> t2.Place)

在SQL server中,您可以获得基于行数的差分的行程顺序和操作,然后放置并尝试类似的操作

您可以使用它作为参考,在USQL中创建类似的查询

样本数据

质疑


试试这个。没有变量,没有特别特别的花哨:

select a1.action, a1.place
  from trip_a a1
    left join trip_a a2
      on a2.trip_order = 
        (select min(trip_order) 
          from trip_a a3 
          where trip_order > a1.trip_order)
  where a1.action != a2.action or a1.place != a2.place or a2.place is null
此处演示:

希望它能在您使用的任何sql上工作,只要支持子查询,它就应该工作

Tt只需找到下一个最高的trip\u id,并加入它,如果没有更高的trip\u顺序,则加入null。然后,它只选择位置、动作或两者都不同的行,或者如果联接表a2中没有位置,则选择该行。位置为空

标准完全更改后编辑

如果要获得完全从基表生成的相同结果,可以执行以下操作:

  select 
         case when a.action = 1 then 'load' when a.action = 0 then 'unload' end as action,
         case when a.action = 1 then o.loadingplace when a.action = 0 then o.unloadingplace end as place
    from trips t
      inner join actions a
        on t.trip_id = a.trip_id
      inner join orders o
        on a.orderid = o.orderid
      left join actions a2
        on a2.roor = 
          (select min(roor) 
             from actions a3
             where a3.roor > a.roor)
      left join orders o2
        on a2.orderid = o2.orderid
      where a.action != a2.action
        or a2.action is null
        or
          case when a.action = 1 then o.loadingplace != o2.loadingplace
               when a.action = 0 then o.unloadingplace != o2.unloadingplace
          end
    order by a.roor asc
这是最新的提琴:


这将为您提供所需的结果。

mysql sql server。你用的是哪一种?我不使用MySQL或SQL server,它是一种特定的USQL语言,但与之类似。trip_order是否总是按顺序递增10?不,不是。它可以是任何数字,但必须是唯一的。所以可能是10,12,55,87。但它不可能是10,10,10,87。@PSVSupporter好的-这有点棘手,但解决了,我想谢谢,但USQL不能以这种方式处理变量。这当然要求您的行程顺序以10步递增,并且您的动作按目的地分组,首先卸载,然后加载。如果行程顺序始终是每10步,但这当然不是它可以是10,12,25,66。。。因为在其他停止之间插入停止,或移动/删除停止。您可以使用行号或类似的方法对中间结果执行此操作。除了sql server标记可能不应该在那里之外。我的意思是,在OP上的注释中,说明这不是真正的sql server环境这可能是我正在寻找的。除了我给出的例子之外,它不是在1表中,而是在三个表中:trip-stops-order[code]行程:tripid 12345停止:tripid matnr routenr vlg行动指令ID 12345 10 1装载a1 12345 10 1卸载b1 12345 10 30 1装载c1 12345 20 10 1卸载d1 12345 20 1装载e1订单指令ID装载地点解开巴黎-雅典-巴黎-雅典。。那么这些信息应该在问题中。您总是可以将提供您在问题中输入的表的查询推到这个查询中,而不是“trip_a”,however@PSVSupporter如果将源表和示例数据放在问题中,我可以更新answer@PSVSupporter对不起,我没看到-你能把你用来获取你发布的初始数据的查询也放进去吗?@PSVSupporter对此毫不在意-我想我是撞到了头。我想你可能把一些动作打错了。
SELECT action,place FROM 
(
    SELECT *,ROW_NUMBER()OVER(ORDER BY trip_order) - ROW_NUMBER()OVER(ORDER BY action,place) n
    FROM @trip
)t
GROUP BY n,action,place
ORDER BY MIN(trip_order)
select a1.action, a1.place
  from trip_a a1
    left join trip_a a2
      on a2.trip_order = 
        (select min(trip_order) 
          from trip_a a3 
          where trip_order > a1.trip_order)
  where a1.action != a2.action or a1.place != a2.place or a2.place is null
  select 
         case when a.action = 1 then 'load' when a.action = 0 then 'unload' end as action,
         case when a.action = 1 then o.loadingplace when a.action = 0 then o.unloadingplace end as place
    from trips t
      inner join actions a
        on t.trip_id = a.trip_id
      inner join orders o
        on a.orderid = o.orderid
      left join actions a2
        on a2.roor = 
          (select min(roor) 
             from actions a3
             where a3.roor > a.roor)
      left join orders o2
        on a2.orderid = o2.orderid
      where a.action != a2.action
        or a2.action is null
        or
          case when a.action = 1 then o.loadingplace != o2.loadingplace
               when a.action = 0 then o.unloadingplace != o2.unloadingplace
          end
    order by a.roor asc
SELECT s.*
FROM stops s LEFT JOIN stops prev ON 
     ( prev.Trip_order < s.Trip_order
       AND NOT EXISTS ( SELECT 'a'
                        FROM stops prev2
                        WHERE prev2.Trip_order < s.Trip_order
                        AND prev2.Trip_order > prev.Trip_order
                       )
      )
WHERE s.Action <> COALESCE(prev.Action, '')
OR s.Place <> COALESCE(prev.Place, '')
ORDER BY s.Trip_order
select a1.action,a1.place
from tripa a1,tripa a2
where a2.trip_order = (select min(trip_order) from tripa a3 where trip_order > a1.trip_order)
and (a1.action != a2.action or a1.place != a2.place) 
or a2.place is null