将匹配列附加到每个结果行

时间:2014-02-02 23:06:13

标签: php mysql sql

我不是一名SQL退伍军人,所以如果这很明显,请原谅我。我正在学习。

我在婚礼邀请系统的数据库中有两张桌子;客人和邀请。一个邀请(邀请)可以包含许多客人。

为了为邀请创建邮件合并,我正在尝试从guest虚拟机表中选择firstname和lastname,其中guest虚拟机的inviteID与其他的相同;有效地返回包含inviteID数据的数据行和每个包含guest虚拟机名称的列。

我的问题是我可以返回数据,但是跨多行不能用于邮件合并。我可以创建一个PHP脚本来进行解决方法,但我想了解如何在纯SQL中实现这一点。

有人可以解决一些问题吗?可以这样做吗?这纯粹是疯了吗?

希望实现:

***************************  1. row ***************************
       inviteID: 39
  inviteURLSlug: thewinnetts
                ....
guestFirstName1: Sid
  guestSurname1: Winnett
guestFirstName2: Claire
  guestSurname2: Winnett

'邀请'表:

+---------------------+--------------+
| Field               | Type         |
+---------------------+--------------+
| inviteID            | int(11)      |
| inviteURLSlug       | varchar(64)  |
| inviteQRValue       | varchar(255) |
| inviteQRImageURL    | varchar(255) |
| inviteAddress1      | varchar(32)  |
| inviteAddress2      | varchar(32)  |
| inviteAddress3      | varchar(32)  |
| inviteCity          | varchar(32)  |
| inviteCounty        | varchar(32)  |
| inviteCountry       | varchar(32)  |
| invitePostcode      | varchar(16)  |
| inviteDateSend      | datetime     |
| inviteDateResponded | datetime     |
| inviteCreated       | datetime     |
| inviteUpdated       | timestamp    |
+---------------------+--------------+

'来宾'表:

+-------------------+--------------+
| Field             | Type         |
+-------------------+--------------+
| guestID           | int(11)      |
| inviteID          | int(11)      |
| guestFirstName    | varchar(32)  |
| guestSurname      | varchar(32)  |
| guestSide         | varchar(8)   |
| guestAttending    | tinyint(1)   |
| guestEmail        | varchar(255) |
| guestPhone        | varchar(32)  |
| guestMobile       | varchar(16)  |
| guestAddress1     | varchar(32)  |
| guestAddress2     | varchar(32)  |
| guestAddress3     | varchar(32)  |
| guestCity         | varchar(32)  |
| guestCounty       | varchar(32)  |
| guestCountry      | varchar(32)  |
| guestPostCode     | varchar(16)  |
| guestProfilePhoto | varchar(64)  |
| guestFoodVeg      | tinyint(1)   |
| guestFoodReq      | varchar(255) |
| guestTwitter      | varchar(15)  |
| guestFacebook     | varchar(32)  |
| guestPlusone      | int(1)       |
| guestCreated      | datetime     |
| guestUpdated      | timestamp    |
+-------------------+--------------+

失败加入尝试和裁剪结果示例:

SELECT * FROM guest INNER JOIN invite on guest.inviteID = invite.inviteID \G


*************************** 64. row ***************************
            guestID: 72
           inviteID: 39
     guestFirstName: Claire
       guestSurname: Winnett
                    .......
*************************** 65. row ***************************
            guestID: 73
           inviteID: 39
     guestFirstName: Sid
       guestSurname: Winnett
                    .......

3 个答案:

答案 0 :(得分:0)

要实现这些结果,需要在PHP中进行额外的处理。 为此,请将您的查询修改为:

SELECT i.*,
  g.guestFirstName,
  g.guestSurname
  GROUP_CONCAT(DISTINCT g.guestFirstName, '|', g.guestSurname ORDER BY g.guestSurname DESC) AS names
FROM invite i
INNER JOIN guest g ON i.inviteID = g.inviteID;

确保将结果作为数组返回。从那里,将连接的结果转换为数组然后遍历它们以设置自定义键名和相应的值(假设您的查询结果是数组格式,变量名称为$ queryresults):

$names = explode(',' $queryresults['names']);
unset($queryresults['names']);

$i = 1;
foreach ($names as $name) {
  $split_name = str_split("|", $name);
  $queryresults['guestFirstName' . $i] = $split_name[0];
  $queryresults['guestSurname' . $i] = $split_name[1];
  $i++;
}

这可以为您提供所需的结果。

答案 1 :(得分:0)

SQL并不擅长此类事情。它希望在集合中工作,集合中的所有项目都是相同的。您要求集合中的两个项目一起被粉碎。这是一个可能的解决方案:

SELECT
  t1.inviteID, 
  t1.guestID, 
  t1.guestFirstName, 
  t1.guestSurname, 
  t2.guestFirstName AS guestFirstName2, 
  t2.guestSurname AS guestSurname2
FROM
  guests as t1
LEFT OUTER JOIN 
  guests as t2
ON t1.inviteID = t2.inviteID
AND t1.guestID <> t2.guestID
WHERE 
 t1.guestID = (select min(t3.guestID) from guests as t3 where t3.inviteID = t1.inviteID)
;

guests表使用两次,一次是在每次邀请时提供第一位访客,第二次是使用LEFT OUTER JOIN提供第二位访客。即使没有第二个,LEFT OUTER也可以确保您获得第一个。其他标准是为了确保你没有连接到它自己的行,你只输出第一个,附加秒数(而不是相反)。

Here is a sample fiddle(在MySQL中)

答案 2 :(得分:0)

这是你想要的东西吗?

在您发表评论后更新。

SELECT GROUP_CONCAT( DISTINCT `guest`.`guestFirstName`,`guest`.`guestSurname`, `invite`.`inviteURLSlug` ) FROM `guest`
LEFT JOIN `invite` ON `invite`.`inviteID` = `guest`.`inviteID`
WHERE `invite`.`inviteID` = 5 

我刚刚制作了两个简单的表格,其中包含最少的测试信息,但很容易扩展到您拥有/想要的任何内容。

您将重复一些字段,因为行数将与来宾数量相关。