我有一张表(简化)看起来像这样:
+----+--------------+-----------+----------------+----------------+--------+---------+
| ID | First name | Last name | Street Address | Postal Address | Country | Spouse |
+----+--------------+-----------+----------------+----------------+---------+--------+
| 1 | Nancy | Fuller | Street 1 | City 1 | USA | 4 |
| 2 | Andrew | Davolio | Way 2 | Town 2 | USA | 0 |
| 3 | Janet | Leverling | Blvd 3 | Village 3 | USA | 0 |
| 4 | Steven | Buchanan | Street 1 | City 1 | USA | 1 |
| 5 | Anne | Dodsworth | Street 1 | City 1 | USA | 0 |
+----+--------------+-----------+----------------+----------------+---------+--------+
如您所见,南希和史蒂文已婚(配偶栏中包含配偶的身份证,如果有的话)并且共同生活。安妮,南希的妹妹,也和他们住在一起(不要轻易评论这些不便)。
现在我要打印这个数据库。我想按姓氏订购,但在打印页面上我有两个选择:
所以有四种情况:
没有分组
它们只是按姓氏排序:
布坎南,史蒂文
Davolio,Andrew
Dodsworth,Anne
富勒,南希
Leverling,Janet
按地址分组 当到达具有相同地址的多个人的第一个人时,所有人都被打印出来(仍然按照组中的姓氏排序):
布坎南,史蒂文
Dodsworth,Anne
富勒,南希
Davolio,Andrew
Leverling,Janet
由配偶分组 当一对夫妇中的第一个人到达时,两个都被打印出来:
布坎南,史蒂文
富勒,南希
Dodsworth,Anne
Davolio,Andrew
Leverling,Janet
按地址和配偶分组 结合上述情况,配偶被优先考虑(因此南希出现在安妮面前,因为她是史蒂夫的配偶)。
布坎南,史蒂文
富勒,南希
Dodsworth,Anne
Davolio,Andrew
Leverling,Janet
我真的希望他们分组,如果可能的话,不只是在彼此之后订购。如上所示,我想要不分组的人之间的空间,并且在分组的人之间没有空间。 这可能只使用MySQL,还是我必须使用PHP?
(我使用PHP 5.5.16和MySQL 5.5.39,PDO对象)
答案 0 :(得分:2)
在此查询中,我将cast语句放在select部分中,以便您可以看到数据是如何布局的。如果需要,可以将它们迁移到ORDER BY,并且只取出firstname,lastname。
SELECT DISTINCT
CASE WHEN p1.id IS NOT NULL THEN 1 ELSE 0 END,
CASE WHEN p2.id IS NOT NULL THEN 1 ELSE 0 END,
CONCAT(p.lastname, ', ', p.firstname)
FROM people p
LEFT JOIN people p1 ON p1.spouse = p.id
LEFT JOIN people p2 ON p2.streetaddress = p.streetaddress
AND p.postaladdress = p2.postaladdress
AND p2.id <> p.id
ORDER BY 1 DESC, 2 DESC, 3 ASC;
SELECT DISTINCT
CASE WHEN p2.id IS NOT NULL THEN 1 ELSE 0 END,
CONCAT(p.lastname, ', ', p.firstname)
FROM people p
LEFT JOIN people p2
ON p2.streetaddress = p.streetaddress
AND p.postaladdress = p2.postaladdress
AND p2.id <> p.id
ORDER BY 1 DESC, 2 ASC;
SELECT DISTINCT
CASE WHEN p1.id IS NOT NULL THEN 1 ELSE 0 END,
CONCAT(p.lastname, ', ', p.firstname)
FROM people p
LEFT JOIN people p1 ON p1.spouse = p.id
ORDER BY 1 DESC, 2 ASC;
SELECT
CONCAT(p.lastname, ', ', p.firstname)
FROM people p;
<强> Fiddle Demo 强>
注意:如果您按顺序保留选择,那么您可以轻松地在应用程序层中添加空格...例如,如果它拉出1然后这意味着订单对于配偶,地址等是真的。如果它是0然后它是假的。所以你可以检查这个值,如果它是0,则开始添加空格
按名称升序执行订单,但在MySQL中无法用另一个配偶或相同地址的名称覆盖它。您可以使用CASE语句检查php是否有配偶,并更改其中的顺序。