在SQL中查询Many-To-Many关系时,Return多个连接作为单行数组?
When Querying Many-To-Many Relationship in SQL, Return Multiple Connections As an Array In Single Row?
基本上,我有 3 个 table、标题、提供者和 provider_titles。
假设它们看起来像这样:
| title_id | title_name |
|------------|----------------|
| 1 | San Andres |
| 2 |Human Centipede |
| 3 | Zoolander 2 |
| 4 | Hot Pursuit |
| provider_id| provider_name |
|------------|----------------|
| 1 | Hulu |
| 2 | Netflix |
| 3 | Amazon_Prime |
| 4 | HBO_GO |
| provider_id| title_id |
|------------|----------------|
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 3 | 1 |
| 3 | 3 |
| 4 | 4 |
所以,显然有多个提供商的标题,是吗?到目前为止典型 many-to-many。
所以我正在做的查询是使用如下的 JOIN:
SELECT * FROM provider_title JOIN provider ON provider_title.provider_id = provider.provider_id JOIN title ON title.title_id = provider_title.title_id WHERE provider.name IN ('Netflix', 'HBO_GO', 'Hulu', 'Amazon_Prime')
好的,现在进入实际问题。我不想返回重复的标题名称,但我确实想要与标题关联的所有提供者。让我用另一个table来解释。这是我通过当前查询返回的内容,原样:
| provider_id| provider_name | title_id | title_name |
|------------|---------------|----------|---------------|
| 1 | Hulu | 1|San Andreas |
| 1 | Hulu | 2|Human Centipede|
| 2 | Netflix | 1|San Andreas |
| 3 | Amazon_Prime | 1|San Andreas |
| 3 | Amazon_prime | 3|Zoolander 2 |
| 4 | HBO_GO | 4|Hot Pursuit |
但我真正想要的是
| provider_id| provider_name |title_id| title_name|
|------------|-----------------------------|--------|-----------|
| [1, 2, 3] |[Hulu, Netflix, Amazon_Prime]| 1|San Andreas|
意思是我只想要不同的标题,但我仍然想要每个标题的相关提供商。 只有 可以通过逻辑迭代返回的行来执行post-sql 查询吗?
根据您的数据库引擎,可能有一个聚合函数可以帮助实现这一点。
例如,this SQLfiddle demonstrates the postgres array_agg函数:
SELECT t.title_id,
t.title_name,
array_agg( p.provider_id ),
array_agg( p.provider_name )
FROM provider_title as pt
JOIN
provider as p
ON pt.provider_id = p.provider_id
JOIN title as t
ON t.title_id = pt.title_id
GROUP BY t.title_id,
t.title_name
其他数据库引擎有等效项。例如:
- mySQL 有 group_concat
- Oracle 有 listagg
- sqlite 有 group_concat(还有!)
如果您的数据库不在上述范围内,您可以google'[您的数据库引擎]聚合逗号分隔的字符串'
基本上,我有 3 个 table、标题、提供者和 provider_titles。
假设它们看起来像这样:
| title_id | title_name |
|------------|----------------|
| 1 | San Andres |
| 2 |Human Centipede |
| 3 | Zoolander 2 |
| 4 | Hot Pursuit |
| provider_id| provider_name |
|------------|----------------|
| 1 | Hulu |
| 2 | Netflix |
| 3 | Amazon_Prime |
| 4 | HBO_GO |
| provider_id| title_id |
|------------|----------------|
| 1 | 1 |
| 1 | 2 |
| 2 | 1 |
| 3 | 1 |
| 3 | 3 |
| 4 | 4 |
所以,显然有多个提供商的标题,是吗?到目前为止典型 many-to-many。
所以我正在做的查询是使用如下的 JOIN:
SELECT * FROM provider_title JOIN provider ON provider_title.provider_id = provider.provider_id JOIN title ON title.title_id = provider_title.title_id WHERE provider.name IN ('Netflix', 'HBO_GO', 'Hulu', 'Amazon_Prime')
好的,现在进入实际问题。我不想返回重复的标题名称,但我确实想要与标题关联的所有提供者。让我用另一个table来解释。这是我通过当前查询返回的内容,原样:
| provider_id| provider_name | title_id | title_name |
|------------|---------------|----------|---------------|
| 1 | Hulu | 1|San Andreas |
| 1 | Hulu | 2|Human Centipede|
| 2 | Netflix | 1|San Andreas |
| 3 | Amazon_Prime | 1|San Andreas |
| 3 | Amazon_prime | 3|Zoolander 2 |
| 4 | HBO_GO | 4|Hot Pursuit |
但我真正想要的是
| provider_id| provider_name |title_id| title_name|
|------------|-----------------------------|--------|-----------|
| [1, 2, 3] |[Hulu, Netflix, Amazon_Prime]| 1|San Andreas|
意思是我只想要不同的标题,但我仍然想要每个标题的相关提供商。 只有 可以通过逻辑迭代返回的行来执行post-sql 查询吗?
根据您的数据库引擎,可能有一个聚合函数可以帮助实现这一点。
例如,this SQLfiddle demonstrates the postgres array_agg函数:
SELECT t.title_id,
t.title_name,
array_agg( p.provider_id ),
array_agg( p.provider_name )
FROM provider_title as pt
JOIN
provider as p
ON pt.provider_id = p.provider_id
JOIN title as t
ON t.title_id = pt.title_id
GROUP BY t.title_id,
t.title_name
其他数据库引擎有等效项。例如:
- mySQL 有 group_concat
- Oracle 有 listagg
- sqlite 有 group_concat(还有!)
如果您的数据库不在上述范围内,您可以google'[您的数据库引擎]聚合逗号分隔的字符串'