有很多正確的方式來做到這一點。一個EXISTS
半連接可能是PostgreSQL的最快的,如果你只是想從不同的訂單和客戶沒有進一步的細節清單以外,至少存在1:
SELECT c.contactname, c.address
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customerid = c.customerid
AND o.orderdate >= '1997-1-1'::date
AND o.orderdate < '1998-1-1'::date
)
ORDER BY contactname;
爲什麼要用?
WHERE o.orderdate >= '1997-1-1'::date
AND o.orderdate < '1998-1-1'::date
相反的:
WHERE date_part('year', orderdate) = 1997
隨着你的表情的PostgreSQL將不得不計算值的每一行的條件,可以檢查之前。在替代形式中,列(按原樣)與兩個常數項匹配。這也可以更容易地使用索引。應該更快。
另請注意我如何使用table aliases使查詢更易於閱讀。
您的第一個查詢由於JOIN
而遭受了行倍增。如果表customer
中的某一行在表orders
中有多個匹配行,則每個訂單都會有一行。你可以修復一個GROUP BY
:
SELECT c.contactname, c.address
FROM customers c
JOIN orders o USING (customerid)
WHERE o.orderdate >= '1997-1-1'::date
AND o.orderdate < '1998-1-1'::date
GROUP BY c.customer_id --- or whatever is the primary key of c
ORDER BY c.contactname
..這是另一種方式來做到這一點。但最可能慢。你會使用這種形式,如果你也想從表orders
檢索其他(彙總)數據..
DISTINCT
將是一個替代GROUP BY
,這樣做主要是同在這個簡單的例子。刪除GROUP BY
條款並在SELECT
後添加DISTINCT
。
您也可以使用DISTINCT
修復您的第二個查詢,而是使用我的第一個示例。
你回來的結果有什麼問題? (我會找到另一種方法來選擇日期,但是在這樣的where子句中的列上執行函數通常是獲得表掃描的一種好方法,也許where orderdate> = 1/1/1997和orderdate <= 12/31/1997或類似的東西)。 – Marvo
因爲在第一種情況下我得到了重複的結果,假設亞歷山大 - 亞歷山大 - 亞歷山大 - 阿納貝拉 - 阿納貝拉檢驗了第二個給我亞歷山大 - 阿納貝拉 - ... – FacundoGFlores
我應該有在選擇和聯繫人姓名之間添加區分?我正在閱讀有關它,子查詢和聯接應該是相同的,但他們是不同的演講正確的? – FacundoGFlores