简体   繁体   English

SQL复杂查询分组(Oracle JPA)

[英]Sql complex group by query (oracle jpa)

id     let      num    dir    ctry
----------------------------------
0       A       10      W      US   <- first row of route (A-W)
1       A       20      W      CA
2       A       30      W      MX
3       B       25      E      US
4       B       30      E      CA
5       B       20      E      CA   <- first row of route (B-E)

I have a table which is composed of segments (1 row = 1 segment) and routes (multiple segments). 我有一个表,该表由网段(1行= 1网段)和路由(多个网段)组成。

A route is composed of segments having the same "let" and "dir" combination. 路线由具有相同“ let”和“ dir”组合的线段组成。 So the first 3 rows is one route, and the last 3 rows is another. 因此,前3行是一条路线,后3行是另一条路线。

The first segment in the route is the row with the smallest num . 路线的第一段是num最小的行。

  • So, row id = 0 is the first segment in route 1, 因此,第id = 0id = 0是路线1中的第一段
  • and the last row id = 5 is the first segment in route 2. 最后一行id = 5是路线2中的第一段。

I want to return the rows that make up a route based on the 1st segment of that route equaling a given country. 我想根据该路线的第一个路段(等于给定的国家/地区)返回组成路线的行。

If I filtered on a "ctry" of CA the result would be the following: 如果我对CA的“尝试”进行了过滤,结果将如下所示:

id     let    num     dir   ctry
--------------------------------
3       B      25      E     US
4       B      30      E     CA
5       B      20      E     CA
 SELECT * 
 FROM YourTable 
 WHERE (let, dir) IN (SELECT distinct let, dir
                      FROM YourTable Y
                      WHERE Y.ctry = 'CA')

OR 要么

 SELECT L.*
 FROM YourTable L
 JOIN (SELECT distinct let, dir
       FROM YourTable Y
       WHERE Y.ctry = 'CA') R
   ON L.let = R.let
  AND L.dir = R.dir

Based on your comment SqlFiddleDemo 根据您的评论SqlFiddleDemo

SELECT R.*
FROM 
     (SELECT let, dir, min(num) as minnum
      FROM Routes t
      GROUP BY let, dir
     )  minT
JOIN  (SELECT t.*
       FROM Routes t      
      )  firstrow
   ON minT.let = firstrow.let
  AND minT.dir = firstrow.dir
  AND minT.minnum = firstrow.num
JOIN  Routes R
   ON firstRow.let = R.let
  AND firstRow.dir = R.dir
  AND firstRow.Ctry = 'CA';

In Oracle, you can do this using analytics function: 在Oracle中,您可以使用分析功能来做到这一点:

select t.*
from (select t.*,
             min(country) keep (dense_rank first order by num) over (partition by let, dir) as first_country
      from t
     ) t
where first_country = 'CA';

JPA is more limited. JPA较为有限。 This might work: 这可能起作用:

select t.*
from t join
     (select let, dir, min(num) as minnum
      from t
      group by let, dir
     ) ld 
     on t.let = ld.let and t.dir = ld.dir join
     t tt
     on tt.let = ld.let and tt.dir = ld.dir and tt.num = ld.minnum
where tt.country = 'CA';

http://sqlfiddle.com/#!9/ae58a/1 http://sqlfiddle.com/#!9/ae58a/1

By using your guys direction I came up with a good solution that is readable. 通过使用你们的指导,我提出了一个易于理解的好解决方案。 Thanks juan and gordon. 感谢胡安和戈登。

SELECT Routes.* FROM Routes
JOIN (SELECT let,dir,min(num) as minnum
      FROM Routes
      GROUP BY let, dir
      ) ld JOIN Routes tt
ON tt.let = ld.let AND tt.dir = ld.dir AND tt.num = ld.minnum 
AND Routes.let = ld.let AND Routes.dir = ld.dir
WHERE tt.ctry = 'CA';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM