[英]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
最小的行。
id = 0
is the first segment in route 1, 因此,第id = 0
行id = 0
是路线1中的第一段 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.