2017-09-10 80 views
0

我有一個名爲deliveries的主表,它與deliveryies_languages有dl,deliveries_markets dm和deliveries_tags dt有delivery_id作爲外鍵的一對多關係。這三張表分別與語言,市場和標籤有一對一的關係。另外,交付,表格與公司有一對一的關係,並且公司_是外部關鍵。以下是我寫的查詢:從多個連接中獲取不同的行SQL

SELECT deliveries.*, languages.display_name, markets.default_name, tags.default_name, companies.name 
FROM deliveries 
JOIN deliveries_languages dl ON dl.delivery_id = deliveries.id 
JOIN deliveries_markets dm ON dm.delivery_id = deliveries.id 
JOIN deliveries_tags dt ON dt.delivery_id = deliveries.id 
JOIN languages ON languages.id = dl.language_id 
JOIN markets ON markets.id = dm.market_id 
JOIN tags ON tags.id = dt.tag_id 
JOIN companies ON companies.id = deliveries.company_id 
WHERE 
deliveries.name ILIKE '%new%' AND 
deliveries.created_by = '5f331347-fb58-4f63-bcf0-702f132f97c5' AND 
deliveries.deleted_at IS NULL 
LIMIT 10 

在這裏我得到冗餘delivery_ids因爲每個delivery_id有多種語言,市場和標籤。我想對不同的delivery_ids使用限制。所以,限制10不應該從上面的連接查詢中給我10條記錄,但是10條記錄中有不同的delivery_id(deliveries.id)。我可能可以在這裏使用派生表的概念,但我不知道我該怎麼做。有人可以幫我解決這個問題。

+0

你正在使用哪個dbms? – jarlh

+0

如何根據delivery_id選擇這10行? (保留幾種語言似乎有點奇怪。) – jarlh

+0

我使用的是PostgreSQL –

回答

0

在Postgres裏,你可以使用distinct on

SELECT DISTINCT ON (d.id) d.*, l.display_name, m.default_name, t.default_name, c.name 
FROM deliveries d JOIN 
    deliveries_languages dl 
    ON dl.delivery_id = d.id JOIN 
    deliveries_markets dm 
    ON dm.delivery_id = d.id JOIN 
    deliveries_tags dt 
    ON dt.delivery_id = d.id JOIN 
    languages l 
    ON l.id = dl.language_id JOIN 
    markets m 
    ON m.id = dm.market_id JOIN 
    tags 
    ON t.id = dt.tag_id JOIN 
    companies c 
    ON c.id = d.company_id 
WHERE d.name ILIKE '%new%' AND 
     d.created_by = '5f331347-fb58-4f63-bcf0-702f132f97c5' AND 
     d.deleted_at IS NULL 
ORDER BY d.id 
LIMIT 10; 

對於更大量的數據,這可能是非常低效的。如果使用這種方式,則可以使用多個聯結表來生成笛卡兒積。但是,對於少量的數據,這應該可以解決您的問題。

+0

這是爲我工作。但你說表演會妨礙。是因爲多個連接還是因爲DISTINCT ON子句?另外,它比使用子查詢更有效嗎? –

+0

謝謝Gordon Linoff –

+0

@NilakshiNaphade。 。 。這是因爲連接在不同維度上生成笛卡爾積。 。 。對於給定的交付,中間結果是語言的數量乘以市場數量乘以標籤數量。 –