Sql 使用三个表进行不重复的查询

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

我有一个包含三个表的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     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。有什么想法吗?