SQL:列出用户的电话号码和电子邮件地址

时间:2015-01-09 11:32:18

标签: sql postgresql

我想在PostgreSQL中进行查询,其中列出了我的用户及其电子邮件地址和电话号码(以逗号分隔),如下所示:

| user1 | email1@mail.com, email2@mail.com | +3612123123, +3623234234 |

表格是:

user - stores the user's data

user_email - stores the user's email addresses

user_phone - stores the user's phone numbers

我试过obvius:

SELECT user.id, user.name
(
  SELECT array_agg(user_email.email)
  FROM user_email
  WHERE user_email.user_id = user.id
) AS EmailAddresses,
(
  SELECT array_agg(user_phone.phone)
  FROM user_phone
  WHERE user_phone.user_id = user.id
) AS PhoneNumbers
FROM user
ORDER BY user.id

但这导致了荒谬的查询时间(34秒)。 比我尝试过:

SELECT user.id, user.name, array_agg(user_email.email), array_agg(user_phone.phone)
FROM user
LEFT JOIN user_email ON user_email.user_id = user.id
LEFT JOIN user_phone ON user_phone.user_id = user.id
GROUP BY user.id
ORDER BY user.id

这会产生非常好的查询时间(大约100毫秒)。 但这样就列出了电话号码和电子邮件地址的每种组合。因此,如果我有3个电子邮件地址和3个电话号码,那么它会列出9个电子邮件地址(每个地址三倍)和9个电话号码。

有没有一种有效的方法来做我想要的事情?

2 个答案:

答案 0 :(得分:1)

DISTINCT也可以在aggregate expressions中使用:

SELECT "user".id, name, array_agg(DISTINCT email) emails, array_agg(DISTINCT phone) phones
FROM "user"
LEFT JOIN user_email ON user_email.user_id = "user".id
LEFT JOIN user_phone ON user_phone.user_id = "user".id
GROUP BY "user".id
ORDER BY "user".id;

注意:如果您只需要以逗号分隔的列表,则可能需要使用string_agg()而不是array_agg()

SQLFiddle

答案 1 :(得分:0)

DISTINCT

SELECT DISTINCT user.id, user.name, array_agg(user_email.email), array_agg(user_phone.phone)
FROM user
LEFT JOIN user_email ON user_email.user_id = user.id
LEFT JOIN user_phone ON user_phone.user_id = user.id
GROUP BY user.id
ORDER BY user.id

INNER加入

SELECT user.id, user.name, array_agg(user_email.email), array_agg(user_phone.phone)
FROM user
INNER JOIN user_email ON user_email.user_id = user.id
INNER JOIN user_phone ON user_phone.user_id = user.id
GROUP BY user.id
ORDER BY user.id

或两者

SELECT DISTINCT user.id, user.name, array_agg(user_email.email), array_agg(user_phone.phone)
FROM user
INNER JOIN user_email ON user_email.user_id = user.id
INNER JOIN user_phone ON user_phone.user_id = user.id
GROUP BY user.id
ORDER BY user.id
相关问题