2010-10-14 27 views
0

我正在使用我們班的PostgreSQL服務器上的SQL進行我的第一個任務。樣品數據庫具有(部分在這裏)模式:PostgreSQL不必要的查詢修剪結果

CREATE TABLE users (
    id int PRIMARY KEY, 
    userStatus varchar(100), 
    userType varchar(100), 
    userName varchar(100), 
    email varchar(100), 
    age int, 
    street varchar(100), 
    city varchar(100), 
    state varchar(100), 
    zip varchar(100), 
    CONSTRAINT users_status_fk FOREIGN KEY (userStatus) REFERENCES userStatus(name), 
    CONSTRAINT users_types_fk FOREIGN KEY (userType) REFERENCES userTypes(name) 
); 

CREATE TABLE events (
    id int primary key, 
    title varchar(100), 
    edate date, 
    etime time, 
    location varchar(100), 
    user_id int, -- creator of the event 
    CONSTRAINT events_user_fk FOREIGN KEY (user_id) REFERENCES users(id) 
); 

CREATE TABLE polls (
    id int PRIMARY KEY, 
    question varchar(100), 
    creationDate date, 
    user_id int, --creator of the poll 
    CONSTRAINT polls_user_fk FOREIGN KEY (user_id) REFERENCES users(id) 
); 

和一堆樣本數據(特別地,127樣本用戶)。

我必須編寫一個查詢來查找過去一年內用戶創建的民意調查數量,以及過去一年中發生的用戶創建的事件數量。訣竅是,如果用戶沒有這樣的投票/事件,那麼我應該在兩列都有0。

我有一個查詢似乎返回正確的數據,但只有116個127用戶,我不明白爲什麼查詢修剪這11個用戶,當WHERE子句只檢查poll/event的屬性。以下是我的查詢:

SELECT u.id, u.userStatus, u.userType, u.email, -- Return user details 
     COUNT(DISTINCT e.id) AS NumEvents, -- Count number of events 
     COUNT(DISTINCT p.id) AS NumPolls -- Count number of polls 
FROM (users AS u LEFT JOIN events AS e ON u.id = e.user_id) LEFT JOIN polls AS p ON u.id = p.user_id 
WHERE (p.creationDate IS NULL OR ((now() - p.creationDate) < INTERVAL '1' YEAR) OR -- Only get polls created within last year 
     e.edate IS NULL OR ((now() - e.edate) < INTERVAL '1' YEAR)) -- Only get events that happened during last year 
GROUP BY u.id, u.userStatus, u.userType, u.email; 

任何幫助將不勝感激。

+1

用少量的用戶測試了你的模式 - 查詢工作正常。檢查爲錯過的用戶插入的數據。 – 2010-10-14 08:28:23

+0

當你忽略「COUNT」聚合列時會發生什麼?你會得到那些你認爲它們是空的行嗎? – Pointy 2010-10-14 14:22:09

回答

0

儘量避免在子查詢中使用DISTINCT。

+0

從COUNT集合中刪除DISTINCT關鍵字並沒有改變任何東西,看起來(除了輸出是按ID排序的,現在是未排序的)。 – Ganon11 2010-10-14 08:21:58

1

使用不同的查詢似乎工作。以下是我最終得到的結果:

SELECT u.id, u.userStatus, u.userType, u.email, COUNT(DISTINCT e.id) AS numevents, COUNT(DISTINCT p.id) AS numpolls 
FROM users AS u LEFT OUTER JOIN (SELECT * FROM events WHERE ((now() - edate) < INTERVAL '1' YEAR)) AS e ON u.id = e.user_id 
    LEFT OUTER JOIN (SELECT * FROM polls WHERE ((now() - creationDate) < INTERVAL '1' YEAR)) AS p ON u.id = p.user_id 
GROUP BY u.id, u.userStatus, u.userType, u.email 
;