【问题标题】:Trying to insert multiple data into one row, but get multiple rows instead尝试将多个数据插入一行,但获取多行
【发布时间】:2012-03-15 23:22:02
【问题描述】:

我正在尝试进行多对多数据库选择,其中我有 事件音乐风格(以及其他)。然而,由于一个事件可以有多种音乐风格,我决定做一个多对多关系模型。

这是我创建的:

SELECT 
     a.* FROM music_types AS a, events_music_types AS b 
WHERE 
     a.id = b.music_type_id 
AND 
     b.event_id = events.ID

并将其插入我的代码中,现在看起来像这样:

$query =    
"SELECT
    events.EVENT_NAME, events.start_datetime, events.end_datetime, events.VENUE_LOCATION, events.PARTY_TYPE, events.IMAGE_URL, events.ENTRANCE_PRICE, 
    venues.VENUE_NAME, venues.BEER_PRICE, venues.WINE_PRICE, SPIRITS_PRICE, 
    party_types.PARTYTYPE, 
    a.*
FROM events
INNER JOIN venues 
    ON events.VENUE_LOCATION = venues.ID
INNER JOIN party_types
    ON events.PARTY_TYPE = party_types.ID
INNER JOIN music_styles AS a, events_music_styles AS b
WHERE start_datetime >= '$DATE_START_SELECTED'
AND end_datetime < '$DATE_END_SELECTED' 
AND a.id = b.music_style_id 
AND b.event_id = events.ID
";
$result = mysql_query($query) or die(mysql_error());

echo "<table border='1'>
<tr>
<th> Poster </th>
<th> Event Name </th>
<th> Venue Name </th>
<th> Party Type </th>
<th> Entrance Price </th>
<th> Music </th>
<th> € of Beer </th>
<th> € of Wine </th>
<th> € of Spirits </th>
</tr>"; 

while($row = mysql_fetch_array($result, MYSQL_ASSOC)){

echo "<tr>";
echo "<td><IMG src='" . $row['IMAGE_URL'] . "'></td>";
echo "<td>" . $row['EVENT_NAME'] . "</td>";
echo "<td>" . $row['VENUE_NAME'] . "</td>";
echo "<td>" . $row['PARTYTYPE'] . "</td>";
echo "<td>" . $row['ENTRANCE_PRICE'] . "</td>";
echo "<td>" . $row['MUSIC_STYLE_NAME'] . "</td>";
echo "<td>" . $row['BEER_PRICE'] . "</td>";
echo "<td>" . $row['WINE_PRICE'] . "</td>";
echo "<td>" . $row['SPIRITS_PRICE'] . "</td>";
echo "</tr>"; 
}

但是,虽然代码确实获取了一个事件的所有音乐风格,但它并没有将它放在一行中,而是将每一行的音乐风格复制到该行的次数。

我将如何将它组合成一行并用逗号分隔音乐风格?谢谢:)!

【问题讨论】:

  • 如果您告诉我们您希望在该列中获得什么结果,我们可以确定如何获得它。
  • 结果是当有多种音乐风格时,行不会分裂。在这种情况下,Music Column 应该只有一行是“Partymix, rap”。

标签: mysql group-concat


【解决方案1】:

将您的查询更改为 -

$query =    
"SELECT
    events.EVENT_NAME,
    events.start_datetime,
    events.end_datetime,
    events.VENUE_LOCATION,
    events.PARTY_TYPE,
    events.IMAGE_URL,
    events.ENTRANCE_PRICE, 
    venues.VENUE_NAME,
    venues.BEER_PRICE,
    venues.WINE_PRICE,
    SPIRITS_PRICE, 
    party_types.PARTYTYPE,
    GROUP_CONCAT(music_styles.MUSIC_STYLE_NAME) AS MUSIC_STYLE_NAME
FROM events
INNER JOIN venues 
    ON events.VENUE_LOCATION = venues.ID
INNER JOIN party_types
    ON events.PARTY_TYPE = party_types.ID
INNER JOIN events_music_styles
    ON events.ID = events_music_styles.event_id
INNER JOIN music_styles
    ON events_music_styles.music_style_id = music_styles.id
WHERE start_datetime >= '$DATE_START_SELECTED'
AND end_datetime < '$DATE_END_SELECTED' 
GROUP BY events.ID
";

您还混合了多种连接样式,之前我已对其进行了更正。

【讨论】:

  • GROUP_CONCAT?这就是我所缺少的! +1
  • 感谢尼科尔斯!然而,即使将music_styles.MUSIC_STYLE_NAME 添加到我的选择区域后,我也遇到了错误Unknown column 'music_styles.MUSIC_STYLE_NAME' in 'field list'
  • 您是否复制了整个查询?我已经更改了联接。
  • 会,但请不要。像这样的混合风格是可怕的。这是一个小错误。我忘了删除INNER JOIN music_styles 之后的表别名。如果您删除 AS a 它应该可以正常工作。
  • 很高兴现在一切正常。最后的快速说明 - 使用 JOIN ... ON 语法更容易阅读,它将所有连接条件放在表名旁边,而不是堵塞 WHERE 子句。
【解决方案2】:

我不知道有任何 mysql 函数可以直接实现这一点。也许有人可以纠正我。你可以查看CREATE AGGREGATE FUNCTION,但乍一看文档似乎很混乱。

另一种选择是在 PHP 中对它们进行分组。首先,您需要将events.ID as eventIDvenues.ID as venueID 添加到您的SELECT 列表中。然后在您的while 循环中,您希望将它们分组为关联数组,并为每个$row 添加一个新值以连接音乐风格。在该循环之后,您会想要遍历新的数据数组,并输出您获得的值。那些相同的将被覆盖,您将拥有新的连接字符串来调用。

不过,在 mysql 中创建聚合函数可能会更快、更有效。您希望创建一个接受所有值、连接它们并返回字符串的方法。在您的 SELECT 中,它的工作方式类似于使用 SUM() 或其他内置聚合。

【讨论】:

  • 谢谢瑞克,我会试着四处寻找,看看能不能想出什么。
  • @Rick - 你描述了GROUP_CONCAT() 函数:) 请参阅下面的答案。
  • @nnichols 已经为你 +1 了,哈哈。我希望存在这样的东西,但不知道从哪里开始寻找。
  • 干杯@Rick。这是一个非常方便的功能,但遗憾的是不是标准的。我认为任何其他 RDBMS 都没有它的本机实现。
【解决方案3】:

在查询中使用适当的GROUP BY 语句并使用GROUP_CONCAT()

【讨论】:

  • 嘿glglgl,通过在末尾插入GROUP BY events.ID,我实现的只是其他重复行消失了,但所有music_styles 数据并未合并到一行中。跨度>
猜你喜欢
  • 1970-01-01
  • 2013-01-01
  • 2021-11-19
  • 2020-07-15
  • 2012-05-16
  • 1970-01-01
  • 2010-11-04
  • 1970-01-01
相关资源
最近更新 更多