Sql:如何仅使用 ID 连接表

Posted

技术标签:

【中文标题】Sql:如何仅使用 ID 连接表【英文标题】:Sql: How to connect tables by just using the ID 【发布时间】:2017-05-29 12:34:02 【问题描述】:

所以我遇到了这个问题:我有 3 个不同的表需要相互连接。它相当复杂,而且我的英语水平也不是很好。让我告诉你:

        T1               T2              T3

  ID_T1 |Name |    |ID_T1|ID_T2|   |ID_T2|Spent|
      1 |James|    |    1|    4|   |   4 | 200 |
      2 |Mike |    |    2|    5|   |   5 | 300 |
      3 |Alex |    |    3|    6|   |   6 | 400 |

基本上,我想使用我在T2 中的ID,在T3 表中连接T1 中的名称所花费的金额。

所以我应该“读到”詹姆斯花了 200 美元,迈克花了 300 美元,亚历克斯花了 400 美元。

要知道的另一件事是 ID 是自动生成的,所以我不应该看到它们。

我在创建表时是否需要注意一些事情,还是需要更多地关注INSERT INTO 命令(我使用 Oracle sql Developer)?

非常感谢! :)

【问题讨论】:

ID_T1 和 ID_T2 是一对一映射的吗?如果是这样,为什么需要 T2 表? 另外,您使用的是哪个数据库? (我猜是甲骨文)。 另外,您是否需要在表 T3 中插入​​具有新 ID_T2 的每笔支出? 这里没有什么复杂的 【参考方案1】:

@Burkinaboy 可能想试试这个

SELECT 
  T1.Name,
  T3.SPent
FROM T1 t0 RIGHT JOIN T2 t1 ON T1.ID_T1 = T2.ID_T1 RIGHT JOIN T3 t2 ON T3.ID_T2=T2.ID_T2

【讨论】:

谢谢!但我没有得到那些 t0 和 t1 ......?我必须把它们放在代码中吗? t0 和 t1 是首字母,在加入表格时需要它们【参考方案2】:

这应该会给你一个预期的输出。

Select a.Name, c.spend
From T1 a, T2 b, T3 c
Where a.Id_T1 = b.Id_T1
AND b.Id_T2 = c.Id_T2 

关于第二个问题,您应该知道表之间的关系,即它们是如何连接的。

根据您的 cmets 更新答案。假设您要硬编码该金额支出列..

Select b.Id_T2 , "300" 
From T1 a ,T2 b
Where a.Id_T1 = b.Id_T1

但在上述情况下,列支出的所有值都是 300。

【讨论】:

感谢您的帮助!这非常有用。但是假设我必须使用 INSERT TO 命令将信息放入 T3 表中,我应该如何进行? @Burkinaboy 没找到你。您想根据 T1 和 T2 在 T3 中插入​​数据吗? 没错!我必须使用 INSERT INTO 命令插入在 T3 中花费的金额。我可以写 INSERT INTO T3 (ID_T2, Spent) VALUES (............,'300')。但我不知道我可以为 ID_T2 写什么,以便将 300 美元关联到 Alex。【参考方案3】:

选择T1 987654323 @,T3 987654325 T1T3 987654327 T1 987654329 T2 987654332 @和T2 987654332 @=T3.ID_T2

【讨论】:

虽然这可能是解决问题的宝贵提示,但一个好的答案也可以证明解决方案。请EDIT 提供示例代码来说明您的意思。或者,考虑将其写为评论【参考方案4】:
select t1.name as name, t3.spent as spent
from t1
join t2 on t2.id_t1 = t1.id_t1
join t3 on t3.id_t2 = t2.id_t2

使用join而不是将所有表都放在FROM子句中。

【讨论】:

【参考方案5】:

假设您在 T3 表中使用新 ID 插入每笔支出,您可以加入三个表并对其进行分组:

select
  T1.ID_T1 ID,
  T1.NAME,
  SUM(T3.SPENT) SPENT
from T1 inner join T2 on T1.ID_T1 = T2.ID_T1
inner join T3 on T2.ID_T2 = T3.ID_T2
GROUP BY T1.ID_T1, T1.NAME;

截至目前,尚不清楚您使用的是哪个数据库。 (我假设它是 Oracle,因为您使用的是 Oracle SQL Developer。类似的解决方案也应该在其他 DBMS 中可用,以防万一。)。

首先,让我们创建表:

create table t1 (
  ID_T1 integer primary key,
  Name varchar2(100)
);

create table t2 (
  ID_T1 integer,
  ID_T2 integer,
  constraint pk primary key(ID_T1,ID_T2)
);

create table t3 (
  ID_T2 integer primary key,
  spent number(10,2)
);

然后创建两个将在插入时使用的序列:

create sequence t1_seq start with 1 increment by 1;
create sequence t2_seq start with 1 increment by 1;

然后是一个显示人均支出的视图:

create or replace view spendings
as
select
  T1.ID_T1 ID,
  T1.NAME,
  SUM(T3.SPENT) SPENT
from T1 inner join T2 on T1.ID_T1 = T2.ID_T1
inner join T3 on T2.ID_T2 = T3.ID_T2
GROUP BY T1.ID_T1, T1.NAME;

然后在上面的视图上创建一个 INSTEAD OF 触发器,以便在基础表中进行正确的插入:

create or replace trigger spendings_trig
instead of INSERT or UPDATE or DELETE on SPENDINGS
for each row
declare
  v_ID_T1 integer;
  v_ID_T2 integer;
  v_name t1.name%type;
begin
  if not inserting then
    raise_application_error(-20001,'Not supported');
  end if;

  begin
    if :new.ID is null then
      v_ID_T1 := T1_SEQ.NEXTVAL;
      insert into T1 (ID_T1, NAME) values (v_ID_T1, :new.NAME);
    end if;
    select ID_T1,NAME into v_ID_T1,v_name from T1
    where ID_T1 = :new.ID;

    if :new.name is not null and v_name <> :new.name then
      raise_application_error(-20002,'Incorrect name entered');
    end if;
  exception
    when no_data_found then
      v_ID_T1 := :new.ID;
      insert into T1 (ID_T1, NAME) values (v_ID_T1, :new.NAME);
  end;

  v_ID_T2 := T2_SEQ.NEXTVAL;
  insert into T2 values (v_ID_T1, v_ID_T2);
  insert into T3 values (v_ID_T2, :new.spent);
end;
/

现在,如果您像这样插入到视图中(假设任何表中都没有数据):

insert into spendings (name, spent) values ('James',100);

T1 会得到一行

ID_T1  NAME
------------
1      James

T2 会得到一行

ID_T1  ID_T2
------------
1      1

T3 会得到一行

ID_T2  SPENT
-------------
1      100

现在如果你这样做:

insert into spendings (id,spent) values (1,100);

不会插入 T1,因为 ID = 1 已经存在行

T2 会得到一行:

ID_T1  ID_T2
------------
1      1
1      2

T3 会得到一行

ID_T2  SPENT
-------------
1      100
2      100

select * from spendings;

将显示:

ID   NAME   SPENT
------------------
1    James  200

【讨论】:

以上是关于Sql:如何仅使用 ID 连接表的主要内容,如果未能解决你的问题,请参考以下文章

连接两个表时如何仅返回最近的日期

如何使用 SQL 查询连接两个表? [复制]

如何将表连接在一起 - SQL

如何使用 SQL 连接合并表? [复制]

mysql 多张表做左连接操作 SQL应该如何写

如何使用 linq 实体仅从 sql 表中选择最后一个条目