2012-04-18 60 views
0

我有兩個表PostgreSQL的尋找獨特的元組

create table JobStaff (
    Job  integer references Job(id), 
    staff  integer references Staff(id), 
    role  integer references JobRole(id), 
    primary key (course,staff,role) 
); 

create table Job (
    cid   integer, 
    branch  integer not null references Branches(id), 
    term  integer not null references Terms(id), 
    primary key (id) 
); 

和IM試圖找到所有不重視他們的工作人員的作業。我會如何去做這件事?

+0

定義中缺少您在主鍵中使用的「course」列嗎?並且'工作表'中缺少'id' .. – 2012-04-18 14:38:36

+0

如果您的代碼示例中顯示的表實際上可以通過複製/粘貼來創建,那麼這會使那些試圖回答您的人變得更容易。一點樣本數據也不會傷害。將來,請在發佈之前在空的測試數據庫中嘗試一下。 – kgrittn 2012-04-18 17:11:12

+0

@ErwinBrandstetter是的,這是我的壞,我複製並粘貼從舊錶。 – SNpn 2012-04-19 04:12:14

回答

2

首先,解決您創建表的查詢,像這樣:

create table JobStaff (
    jobid   integer references Job(id), 
    staffid  integer references Staff(id), 
    roleid  integer references JobRole(id), 
    primary key (jobid,staffid,roleid) 
); 

create table Job (
    id   integer, 
    branch  integer not null references Branches(id), 
    term  integer not null references Terms(id), 
    primary key (id) 
); 
  • JobStaff的主科y應該使用jobid而不是courseid;
  • Job的第一列應該是id而不是cid;
  • 我推薦在使用對id列的引用時使用有意義的列名,如jobid

然後爲您的查詢,你需要這樣的事:

SELECT * FROM Job 
WHERE id NOT IN (SELECT DISTINCT jobid FROM JobStaff); 
1

一種可能的方式:

SELECT * 
FROM job j 
LEFT JOIN jobstaff js ON js.job = j.id 
WHERE js.job IS NULL; 

我寫了一個比較全面的答案這種問題就在昨天上dba.SE: https://dba.stackexchange.com/a/16651/3684

1

使用弗朗西斯普的答案的定義,但REFERENCES省略不定義的表,我的建議是(的變體從歐文Brandstetter修改的全面的答案的選項,他掛在他的回答)PostgreSQL的版本8.4或更高版本之一:

SELECT * 
    FROM Job j 
    WHERE NOT EXISTS (SELECT * FROM jobstaff js WHERE js.jobid = j.id); 

在最近版本的PostgreSQL,這將優化一樣Erwin的回答,除了它只會顯示Job的列,這似乎是你想要的。較窄的行(省略不需要的列)可能會在規模上稍微好一些。在較早版本的PostgreSQL中(版本8.4之前),使用Erwin答案中顯示的選項可能會獲得更好的性能;在8.4中添加了半連接和反連接優化,並且LEFT JOIN技巧是模擬它的最佳方式。

請注意,在這種情況下不需要DISTINCT

對於PostgreSQL中的這種情況,我建議不要使用NOT IN。雖然它在邏輯上並不重要,因爲PRIMARY KEY約束會隱式地強制涉及的列到NOT NULL,NOT IN在涉及到NULL的列時會有令人驚訝的語義,並且處理這些語義的邏輯效率不如NOT EXISTSLEFT JOIN那樣高效。 PostgreSQL不會刻錄處理時間,以查看參數是否可證明爲NOT NULL,因此無論如何您都會得到最差的優化。