2017-01-03 87 views
2

表創建如何克服MySQL的子查詢返回多個1行「的錯誤,並選擇所有相關記錄

CREATE TABLE `users` (
    `id` INT UNSIGNED NOT NULL, 
    `name` VARCHAR(100) NOT NULL, 
    PRIMARY KEY(`id`) 
); 

CREATE TABLE `email_address` (
    `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    `user_id` INT UNSIGNED NOT NULL, 
    `email_address` VARCHAR(50) NOT NULL, 
    INDEX pn_user_index(`user_id`), 
    FOREIGN KEY (`user_id`) REFERENCES users(`id`) ON DELETE CASCADE, 
    PRIMARY KEY(`id`) 
); 

數據插入

INSERT INTO users (id, name) VALUES (1, 'Mark'), (2, 'Tom'), (3, 'Robin'); 

INSERT INTO email_address (user_id, email_address) VALUES 
(1, '[email protected]'), (1, '[email protected]'), (1, '[email protected]'), 
(2, '[email protected]'), (2, '[email protected]'), (2, '[email protected]'), 
(3, '[email protected]'), (3, '[email protected]'), (3, '[email protected]'); 

SQL查詢

SELECT usr.name AS name 
    , (SELECT email.email_address 
      FROM email_address AS email 
     WHERE email.user_id = usr.id) AS email 
    FROM users AS usr;  

通過使用上面我的MySQL查詢,我如何避免MySQL錯誤'子查詢返回多於一行'併爲特定用戶選擇所有相關電子郵件地址,如下所示。謝謝。

+----------+-------------------------------------------------+ 
| name |      email      | 
+----------+-------------------------------------------------+ 
| Mark | [email protected], [email protected], [email protected] | 
| Tom | [email protected], [email protected], [email protected]  | 
| Robin | [email protected], [email protected], [email protected] |     
+----------+----------+--------------------------------------+ 
+1

GROUP_CONCAT是一個possibility-但我真的懷疑這是否是一種有用的方式來返回數據。 – Strawberry

回答

-1

你在email_address表上做了一個不明確的subselect語句。換句話說:您正在嘗試在您的子選擇中選擇多行來進行單行選擇。考慮一下,我會問你這個問題:「數據庫如何用你的查詢來決定選擇哪個電子郵件地址?」答案是它不能,因爲你的查詢沒有指定使用哪個電子郵件地址。因此你的錯誤。

您可以將您的子選擇限制爲1個值。下面是如何可能看:

SELECT usr.name AS name, 
    (SELECT email.email_address 
    FROM email_address AS email 
    WHERE email.user_id = usr.id 
    LIMIT 1) 
AS email 
FROM users AS usr; 

不過,你最好的選擇可能是通過電子郵件發送給潛在的電子郵件所有。爲此,你需要一個JOIN條款可能被結構是這樣的:

SELECT usr.name AS name, addr.email AS email 
FROM users AS usr 
LEFT JOIN email_address AS addr ON (addr.user_id=usr.id); 

這將會給你一個選擇行的是用戶和電子郵件地址的組合。這意味着您將爲具有多個電子郵件地址關聯的任何用戶返回多行。那就是你可以迭代所有返回的行併發送所有用戶的電子郵件。如果有某種方法可以識別主要電子郵件地址,那麼您可能只需向主要電子郵件發送電子郵件。

+0

我很想聽聽爲什麼這是被拒絕的。對負面意見的反饋似乎對每個人都是浪費時間。 – SwampDev

0

我寧願做這樣的而不是使用子查詢

select 
    GROUP_CONCAT(ea.email_address) as emails, 
    u.name 
    from 
    users u 
    left join email_address ea ON (u.id=ea.user_id) 
    group by u.id,u.name 
相關問題