Sql 使用三个表进行不重复的查询
我有一个包含三个表的oracle数据库。第一个表包含ID为X、Y的点,第二个表包含关于线的信息。第三个表在第一个表的点和第二个表的行之间有连接 这里有一个小例子 第一个表点:Sql 使用三个表进行不重复的查询,sql,database,oracle,Sql,Database,Oracle,我有一个包含三个表的oracle数据库。第一个表包含ID为X、Y的点,第二个表包含关于线的信息。第三个表在第一个表的点和第二个表的行之间有连接 这里有一个小例子 第一个表点: ID_POINT X Y 1 -5 40.21 2 -3 41.23 3 -4.12 41.56 4 -7.34 42.68 第二个表格行: ID_LINE
ID_POINT X Y
1 -5 40.21
2 -3 41.23
3 -4.12 41.56
4 -7.34 42.68
第二个表格行:
ID_LINE NAME
100 LINE1
200 LINE2
第三个表将第二个表的行与第一个表连接的两个点连接起来
ID FROM TO
1 1 100
2 100 2
3 2 100
4 100 1
FROM和TO是来自第一个表和第二个表的ID。在本例中可以看到,点1连接到线100,线100连接到点2,因此在端点处,线100将点1连接到点2。
您还可以按相反顺序查看连接:点2与线200和线100与点1
我需要在oracle中生成一个查询,该查询返回一个包含所有行及其坐标的表,不重复,因此本例中的第100行应该是一次,而不是两次,因为我不需要知道相反的顺序。对于本例,该表应为:
ID_LINE X Y X1 Y2
100 -5 40.21 -3 41.23
本例仅显示第100行,但会有更多行
我正在使用此查询,但无法正常工作。有什么想法吗
SELECT * FROM
(
SELECT LN.ID_LINE,
P1.X X,
P1.Y Y,
P2.X X,
P2.Y Y,
ROW_NUMBER() OVER(PARTITION BY ID_LINE ORDER BY SRC1.FROM) ORDER
FROM
(
SELECT *
FROM LINES
) LN,
CONNECTIONS SRC1,
CONNECTIONS SRC2,
POINTS P1,
POINTS P1
WHERE SRC1.TO(+)=LN.ID_LINE AND
SRC2.FROM(+)=LN.ID_LINE AND
P1.ID_POINT(+)=SRC1.FROM AND
P2.ID_POINT(+)=SRC2.TO
)
WHERE ORDER=1
我认为这个查询将只显示每一行一次。诀窍是在case语句中始终按顺序选择from和to id,以便将连接id、p1、p2和id、p2、p1视为相同的连接
SELECT
L.ID_LINE,
L.NAME
P1.X1,
P1.Y1,
P2.X1,
P2.Y2
FROM
LINES L
JOIN (
SELECT DISTINCT
L.ID_LINE,
CASE(WHEN C1.TO > C2.FROM THEN C1.TO ELSE C2.FROM END) FROM_ID,
CASE(WHEN C1.TO < C2.FROM THEN C1.TO ELSE c2.FROM END) TO_ID
FROM
LINES L
JOIN CONNECTIONS C1 ON C1.FROM = L.ID_LINE
JOIN CONNECTIONS C2 ON C2.TO = L.ID_LINE
) t1 ON t1.LINE_ID = L.LINE_ID
JOIN POINTS P1 ON P1.ID_POINT = t1.FROM_ID
JOIN POINTS P2 ON P2.ID_POINT = t1.TO_ID
让我首先提到,这是一个非常糟糕的数据库设计。假设线100连接点100和200。然后你会得到这些连接:
ID FROM TO
1 100 100
2 100 200
3 200 100
4 100 100
你看,在你的第三张桌子上,你无法从技术上看到什么是点,什么是线。此外:一个指向一条指向一个点的线的点???不直线以一点开始,以另一点结束。因此,你应该只有两张桌子,而不是三张桌子;点表和线表如下所示:
ID_LINE NAME FROM_ID_POINT TO_ID_POINT
100 LINE1 1 2
200 LINE2 3 4
另一点是,列名不应使用FROM之类的关键字
然而,即使给出了糟糕的设计,问题也应该是可以解决的。让我们假设ID始终只能是点或线。所以我们必须先找出,什么是点,什么是线。因此,我们找到所有的线和它们的所有点。然后按直线分组,找到两个关联点:最小关联点和最大关联点;应该只有这两个。然后与points表连接,得到x和y
select line.id_line, p1.x as x1, p1.y as y1, p2.x as x2, p2.y as y2
from
(
select x.id_line, min(x.id_point) as id_start_point, max(x.id_point) as id_end_point
from
(
select
case when l.id is null then c.to else c.from end as id_line,
case when l.id is null then c.from else c.to end as id_point
from connections c
left outer join lines l on l.id = c.from
) x
group by x.id_line
) line
join points p1 on p1.id_point = line.id_start_point
join points p2 on p2.id_point = line.id_end_point;
你好谢谢你的回答!我不喜欢数据库设计,但我不能改变它>;我已经更正了我的答案。就像你说的,只是名字有点混乱,没什么了。嗨,伙计!我还需要从表行中获取所有列,因此我在from之前添加了内部select l.*,在另一个select中添加了x.*,但得到的是一个错误,而不是GROUP BY expresion。有什么想法吗?