2016-06-21 33 views
0

我正在實現一個應用程序,該應用程序提供多個場所的開放時間。我的數據庫實現的簡化版本,由兩個表組成:SQL內部連接中的結果重複與一對多關係

+-----------+ +------------------+ 
| Venue | | opening_hour | 
+-----------+ +------------------+ 
| venue_id | | opening_hour_id | 
| name | |  day  | 
+-----------+ | close_time  | 
       | open_time  | 
       | venue_id  | 
       +------------------+ 

在這種情況下,有地點和開放時間之間的一個一對多的關係。

現在,我想檢索數據庫中可用的所有場地及其相應的開放時間的列表。爲了解決這個問題,我使用下面的代碼:

SELECT ven.name as name, oh.day as day 
FROM venue ven INNER JOIN opening_hour oh 
ON oh.venue_id = ven.venue_id 

有了這個實施,每天的開放時間,我得到場地名稱和天值的行的結果。這意味着如果一個場地每週六天開放,我會收到6個同名的相應日子。因此,我發現自己需要處理服務器端的大量重複數據。

我可以從我的小型數據庫知識中想到的唯一兩種解決方案是遵循當前的解決方案或提取所有場地,然後爲其中的每一個執行單個查詢以提取其開放時間。後者顯然是更糟糕的解決方案,因爲它需要大量的數據庫請求。

任何人都可以採取更好的方法嗎?理想的做法是收到一個包含場地名稱和所有開放時間形成的陣列的行。

注意:不確定在這種情況下這是否相關,但我正在使用PostgreSQL數據庫。

+0

在'select'之後加上'distinct'? –

+0

@VaoTsun,nope,需要某種GROUP BY。 – jarlh

+0

然後'string_agg(opening_hour,',')over(由oh.venue_id分區)' –

回答

1

這將給地點名稱和所有天的數組時,場地是開放的:

SELECT ven.name, array_agg(oh.day) 
FROM venue ven 
    NATURAL JOIN opening_hour oh 
GROUP BY ven.name; 
+0

太棒了,非常感謝Laurenz! – ShEsKo

+0

如果我想在array_agg()函數中放置完整的表格細節,該怎麼辦? – ShEsKo

+0

如果你願意,你可以使用'array_agg(ROW(oh.day,oh.close_time,oh.open_time))'。 –

0

對於使用MSSQL的那些;

SELECT 
    v.name, 
    REPLACE(REPLACE(REPLACE('['+(
     SELECT 
      '''' + convert(nvarchar(max),s2.open_time) + '''' as a 
     FROM opening_hour s2 
     WHERE s2.venue_id= s.venue_id 
     FOR XML PATH('') 
    ) + ']','<a>',''),'</a>',','),',]',']') as opening_hours 
FROM opening_hour s 
INNER JOIN Venue v on v.venue_id = s.venue_id 
GROUP BY s.venue_id,v.name 

這裏要注意的是,這並不返回數據類型數組。它只是一個數組格式的字符串。