SQL 内部连接中的结果重复与一对多关系
result repetition in SQL inner join with one to many relationship
我正在实施一个应用程序,该应用程序提供多个场所的开放时间。我的数据库实现的简化版本包含两个表:
+-----------+ +------------------+
| 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 天,我将收到 6 行具有相同名称和相应日期的行。结果,我发现自己有很多必须在服务器端操作的重复数据。
根据我的小数据库知识,我能想到的唯一两个解决方案是遵循当前解决方案或提取所有场所,然后对每个场所执行一次查询以提取其开放时间。后者显然是更糟糕的解决方案,因为它需要大量的数据库请求。
谁能提出更好的方法?理想的情况是接收包含场地名称的行和由所有开放时间组成的数组。
注意:不确定这在这种情况下是否相关,但我使用的是 PostgreSQL 数据库。
这将给出场地名称和场地开放所有日期的数组:
SELECT ven.name, array_agg(oh.day)
FROM venue ven
NATURAL JOIN opening_hour oh
GROUP BY ven.name;
对于使用 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
这里要注意,这不是return数据类型Array。它只是一个数组格式的字符串。
我正在实施一个应用程序,该应用程序提供多个场所的开放时间。我的数据库实现的简化版本包含两个表:
+-----------+ +------------------+
| 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 天,我将收到 6 行具有相同名称和相应日期的行。结果,我发现自己有很多必须在服务器端操作的重复数据。
根据我的小数据库知识,我能想到的唯一两个解决方案是遵循当前解决方案或提取所有场所,然后对每个场所执行一次查询以提取其开放时间。后者显然是更糟糕的解决方案,因为它需要大量的数据库请求。
谁能提出更好的方法?理想的情况是接收包含场地名称的行和由所有开放时间组成的数组。
注意:不确定这在这种情况下是否相关,但我使用的是 PostgreSQL 数据库。
这将给出场地名称和场地开放所有日期的数组:
SELECT ven.name, array_agg(oh.day)
FROM venue ven
NATURAL JOIN opening_hour oh
GROUP BY ven.name;
对于使用 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
这里要注意,这不是return数据类型Array。它只是一个数组格式的字符串。