cve*_*ver 8 php mysql sorting join
我有3张桌子:人,电话和电子邮件.每个人都有一个独特的ID,每个人可以有多个号码或多个电子邮件.
简化它看起来像这样:
+---------+----------+
| ID | Name |
+---------+----------+
| 5000003 | Amy |
| 5000004 | George |
| 5000005 | John |
| 5000008 | Steven |
| 8000009 | Ashley |
+---------+----------+
+---------+-----------------+
| ID | Number |
+---------+-----------------+
| 5000005 | 5551234 |
| 5000005 | 5154324 |
| 5000008 | 2487312 |
| 8000009 | 7134584 |
| 5000008 | 8451384 |
+---------+-----------------+
+---------+------------------------------+
| ID | Email |
+---------+------------------------------+
| 5000005 | Smithley@goodmail.com.com |
| 5000005 | Smithley.j@gmail.com |
| 5000008 | Smithley@gmail.com |
| 5000008 | tech@goodmail.com |
| 5000008 | feler@campus.uni.com |
| 8000009 | Ashley.hill86@gmail.com |
| 5000004 | georgestanko@hotmail.com |
+---------+------------------------------+
Run Code Online (Sandbox Code Playgroud)
我试图加入他们,没有重复.当我尝试仅与人们联系电子邮件或仅与人们联系电话时,它的效果很好.
SELECT People.Name, People.ID, Phones.Number
FROM People
LEFT OUTER JOIN Phones ON People.ID=Phones.ID
ORDER BY Name, ID, Number;
+----------+---------+-----------------+
| Name | ID | Number |
+----------+---------+-----------------+
| Steven | 5000008 | 8451384 |
| Steven | 5000008 | 24887312 |
| John | 5000005 | 5551234 |
| John | 5000005 | 5154324 |
| George | 5000004 | NULL |
| Ashley | 8000009 | 7134584 |
| Amy | 5000003 | NULL |
+----------+---------+-----------------+
SELECT People.Name, People.ID, Emails.Email
FROM People
LEFT OUTER JOIN Emails ON People.ID=Emails.ID
ORDER BY Name, ID, Email;
+----------+---------+------------------------------+
| Name | ID | Email |
+----------+---------+------------------------------+
| Steven | 5000008 | Smithley@gmail.com |
| Steven | 5000008 | tech@goodmail.com |
| Steven | 5000008 | feler@campus.uni.com |
| John | 5000005 | Smithley@goodmail.com.com |
| John | 5000005 | Smithley.j@gmail.com |
| George | 5000004 | georgestanko@hotmail.com |
| Ashley | 8000009 | Ashley.hill86@gmail.com |
| Amy | 5000003 | NULL |
+----------+---------+------------------------------+
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试加入人们的电子邮件和电话时 - 我得到了这个:
SELECT People.Name, People.ID, Phones.Number, Emails.Email
FROM People
LEFT OUTER JOIN Phones ON People.ID = Phones.ID
LEFT OUTER JOIN Emails ON People.ID = Emails.ID
ORDER BY Name, ID, Number, Email;
+----------+---------+-----------------+------------------------------+
| Name | ID | Number | Email |
+----------+---------+-----------------+------------------------------+
| Steven | 5000008 | 8451384 | feler@campus.uni.com |
| Steven | 5000008 | 8451384 | Smithley@gmail.com |
| Steven | 5000008 | 8451384 | tech@goodmail.com |
| Steven | 5000008 | 24887312 | feler@campus.uni.com |
| Steven | 5000008 | 24887312 | Smithley@gmail.com |
| Steven | 5000008 | 24887312 | tech@goodmail.com |
| John | 5000005 | 5551234 | Smithley@goodmail.com |
| John | 5000005 | 5551234 | Smithley.j@gmail.com |
| John | 5000005 | 5154324 | Smithley@goodmail.com |
| John | 5000005 | 5154324 | Smithley.j@gmail.com |
| George | 5000004 | NULL | georgestanko@hotmail.com |
| Ashley | 8000009 | 7134584 | Ashley.hill86@gmail.com |
| Amy | 5000003 | NULL | NULL |
+----------+---------+-----------------+------------------------------+
Run Code Online (Sandbox Code Playgroud)
会发生什么 - 如果一个人有2个号码,他的所有电子邮件都会被显示两次(它们无法排序!这意味着它们不能被@last删除)
底线,和@last一起玩,我想最终得到像这样的东西,但是如果我没有以正确的方式排列ORDER列,那么@last将无法工作 - 这似乎是一个大问题.Orderin the电子邮件列.因为从上面的例子看:
史蒂文有2个电话号码和3封电子邮件.每个电子邮件都会出现带有号码的JOIN电子邮件 - 因此无法排序的重复值(SORT BY对它们不起作用).
**THIS IS WHAT I WANT**
+----------+---------+-----------------+------------------------------+
| Name | ID | Number | Email |
+----------+---------+-----------------+------------------------------+
| Steven | 5000008 | 8451384 | feler@campus.uni.com |
| | | 24887312 | Smithley@gmail.com |
| | | | tech@goodmail.com |
| John | 5000005 | 5551234 | Smithley@goodmail.com |
| | | 5154324 | Smithley.j@gmail.com |
| George | 5000004 | NULL | georgestanko@hotmail.com |
| Ashley | 8000009 | 7134584 | Ashley.hill86@gmail.com |
| Amy | 5000003 | NULL | NULL |
+----------+---------+-----------------+------------------------------+
Run Code Online (Sandbox Code Playgroud)
现在我被告知最好将电子邮件和号码保存在单独的表中,因为可以有很多电子邮件.因此,如果它是如此常见的事情,那么什么不是一个简单的解决方案?
我也很满意PHP解决方案.
如果我使用GROUP_CONTACT这样做,我会得到满意的结果,但它看起来并不漂亮:我不能在它旁边加上"电子邮件类型=工作".
SELECT People.Ime,
GROUP_CONCAT(DISTINCT Phones.Number),
GROUP_CONCAT(DISTINCT Emails.Email)
FROM People
LEFT OUTER JOIN Phones ON People.ID=Phones.ID
LEFT OUTER JOIN Emails ON People.ID=Emails.ID
GROUP BY Name;
+----------+----------------------------------------------+---------------------------------------------------------------------+
| Name | GROUP_CONCAT(DISTINCT Phones.Number) | GROUP_CONCAT(DISTINCT Emails.Email) |
+----------+----------------------------------------------+---------------------------------------------------------------------+
| Steven | 8451384,24887312 | Smithley@gmail.com,tech@goodmail.com,feler@campus.uni.com |
| John | 5551234,5154324 | Smithley@goodmail.com,Smithley.j@gmail.com |
| George | NULL | georgestanko@hotmail.com |
| Ashley | 7134584 | Ashley.hill86@gmail.com |
| Amy | NULL | NULL |
+----------+----------------------------------------------+---------------------------------------------------------------------+
Run Code Online (Sandbox Code Playgroud)
你想要的实际上根本不是你想要的,如果这有意义的话......你实际上不能用数据库输出以编程方式做任何事情,你需要用它做一些事情(除非你只是运行一个查询直接在您的数据库上)。
既然您说过“我也对 PHP 解决方案感到满意”。...你真正想要的是像 PHP“用户”对象这样的东西(当然这都是假设的):
<?php
class User {
private $_id;
private $_telNos = array();
private $_emails = array();
public function __construct($iUserId = null, $oDatabaseAbstractionObject = null) {
if(!is_null($iUserId)) $this->setId($iUserId);
if(!is_null($oDatabaseConnectionObject)) $this->load($iUserId, $oDatabaseAbstractionObject);
}
public setId($iUserId) {
$this->_id = (int) $iUserId;
}
public getId() {
return $this->_id;
}
/* telephone and email setters and getters */
public function load($iUserId, $oDatabaseAbstractionObject) {
/* error trapping - for example if $iUserId is null */
$this->setTelNos($oDatabaseAbstractionObject->readTelNos($iUserId));
$this->setEmails($oDatabaseAbstractionObject->readEmails(iUserId));
}
}
?>
Run Code Online (Sandbox Code Playgroud)
然后,您的数据库抽象对象只需要执行一些非常简单的查询来读取您的用户、用户电子邮件和电话号码表,并将结果作为数组返回,然后您可以将其直接放入 PHP 对象中。例如:
<?php
/**
* this implements a database connection object as a private class member
*/
class DBUser {
private $_conn;
/* constructor other functionality */
/**
* method to pass an SQL query to the database and return an array of results
*/
public function readTelNos($iUserId) {
return $this->_conn->read("SELECT `number` from `tel` WHERE `user_id` = " . (int) $iUserId);
}
}
?>
Run Code Online (Sandbox Code Playgroud)
这会将您的问题分解为更小、更容易处理的问题,并将它们全部包装在您可以实际使用的漂亮 PHP 对象中。
您的用户对象将有一个列表,如果电话号码和电子邮件可以使用类似的内容轻松检索$oUser->getEmails();,如果它们作为关联数组存储在对象内,您甚至可以通过“标签”检索它们$oUser->getEmail('work');