簡體   English   中英

如何連接具有相同主鍵名稱但不同值的兩個表

[英]How to join two tables with same primary key name but different values

我今天了解了“獨家實體”。 我有以下ER圖:

在此處輸入圖像描述

擁有 2 個獨家實體。 當我通過電源設計器創建工具執行物理數據 model 時,它解析為

在此處輸入圖像描述

現在我想在一個表中加入並顯示 id 和 room_name

我想要得到的結構是:

room_id | room_name

房間和卧室的 room_id 是不同的。 例如,卧室的 ID 為 1-10,廚房的 ID 為 11-20。

我覺得我可能有一個糟糕的設計,因為我嘗試的連接並沒有得到我想要的結果。

我最好的猜測是使用像*這樣的自然連接

SELECT room_id, room_name 
FROM bedroom 
NATURAL JOIN kitchen;

這將返回正確的格式,但結果為空。

此外,我希望得到一個格式為:

room_id | roon_name | bedCount | chairCount

您可以將兩個表合並在一起,例如:

select room_id, room_name
from bedroom
union 
select room_id,room_name
from kitchen

您可以完全按照您的要求使用完整的外部連接:

select room_id, room_name, b.bedcount, k.chaircount
from   bedroom b full outer join kitchen k using (room_id, room_name)
;

這幾乎等同於您嘗試的查詢 - 但您需要一個natural FULL OUTER join而不是您嘗試的(內部) natural join聯接。 但是請注意,出於各種原因,許多(大多數?)從業者對natural join語法持懷疑態度。 我上面演示的using子句似乎更容易被接受。 (當然,即使使用自然連接,您最好還是在 output 中專門命名您想要的列。)

盡管對於這種情況,更常見的方法是簡單的union all

select room_id, room_name, bedcount, cast (null as number) as chaircount
from   bedroom
UNION ALL
select room_id, room_name, null    , chaircount
from   kitchen
;

您不能加入它們,因為在加入這些表的表之間沒有任何共同點。 你需要做的是給表格一個他們可以加入的公共列; 例如房間將在建築物中,因此創建一個buildings表,然后每個rooms都應包含包含建築物的外鍵。

IE

CREATE TABLE buildings (
  id   INT
       GENERATED ALWAYS AS IDENTITY
       CONSTRAINT buildings__id__pk PRIMARY KEY,
  name VARCHAR2(20)
       NOT NULL
);

CREATE TABLE rooms (
  id          INT
              GENERATED ALWAYS AS IDENTITY
              CONSTRAINT rooms__id__pk PRIMARY KEY,
  building_id INT
              NOT NULL
              CONSTRAINT rooms__building_id__fk REFERENCES buildings (id),
  room_name   VARCHAR2(20)
              NOT NULL,
  CONSTRAINT rooms__id__rn__u UNIQUE ( id, room_name )
);

CREATE TABLE kitchens (
  id          INT
              CONSTRAINT kitchens__id__pk PRIMARY KEY,
  room_name   VARCHAR2(20)
              GENERATED ALWAYS AS ( 'kitchen' )
              NOT NULL,
  chairCount  INT,
  CONSTRAINT kitchens__id__rn__fk
    FOREIGN KEY ( id, room_name ) REFERENCES rooms ( id, room_name )
);

CREATE TABLE bedrooms (
  id          INT
              CONSTRAINT bedrooms__id__pk PRIMARY KEY,
  room_name   VARCHAR2(20)
              GENERATED ALWAYS AS ( 'bedroom' )
              NOT NULL,
  bedCount    INT,
  CONSTRAINT bedrooms__id__rn__fk
    FOREIGN KEY ( id, room_name ) REFERENCES rooms ( id, room_name )
);

然后,如果您:

INSERT INTO buildings ( id, name ) VALUES ( DEFAULT, 'Building1' );
INSERT INTO rooms ( id, building_id, room_name ) VALUES ( DEFAULT, 1, 'kitchen' );
INSERT INTO rooms ( id, building_id, room_name ) VALUES ( DEFAULT, 1, 'bedroom' );
INSERT INTO kitchens ( id, chairCount ) VALUES ( 1, 42 );
INSERT INTO bedrooms ( id, bedCount ) VALUES ( 2, 13 );

然后:

SELECT b.id AS building_id,
       b.name AS building_name,
       rk.id AS kitchen_id,
       k.chairCount,
       rb.id AS bedroom_id,
       br.bedCount
FROM   buildings b
       LEFT OUTER JOIN rooms rk
       ON ( b.id = rk.building_id AND rk.room_name = 'kitchen' )
       LEFT OUTER JOIN kitchens k
       ON ( rk.id = k.id AND rk.room_name = k.room_name )
       LEFT OUTER JOIN rooms rb
       ON ( b.id = rb.building_id AND rb.room_name = 'bedroom' )
       LEFT OUTER JOIN bedrooms br
       ON ( rb.id = br.id AND rb.room_name = br.room_name )

輸出:

  BUILDING_ID | 建築物名稱 | 廚房_ID | 椅子數 | 卧室_ID | 床數 ----------: |:------------ |  ---------: |  ---------: |  ---------: |  --------: 1 |  1號樓 |  1 |  42 |  2 |  13

db<> 在這里擺弄

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM