不使用 GROUP_CONCAT 的原因?

2023-12-06

我刚刚发现了这个非常有用的 MySQL 函数GROUP_CONCAT。它对我来说似乎非常有用并且过于简单化,以至于我实际上害怕使用它。主要是因为我开始网络编程已经有一段时间了,而且我从未在任何地方见过它。一个很棒的用法示例如下

Table clients每个客户端保存一行具有唯一 ID 的客户端(你不会说...)。
Table currencies有 3 列client_id, currency and amount.

现在如果我想获得用户 15name来自clients表及其余额,使用数组覆盖的“旧”方法我必须使用以下 SQL

SELECT id, name, currency, amount 
FROM clients LEFT JOIN currencies ON clients.id = client_id 
WHERE clients.id = 15

然后在 php 中,我必须循环遍历结果集并进行数组覆盖(我真的不太喜欢,特别是在大量结果集中),例如

$result = array();
foreach($stmt->fetchAll() as $row){
    $result[$row['id']]['name'] = $row['name'];
    $result[$row['id']]['currencies'][$row['currency']] = $row['amount'];
}

但是,通过新发现的功能,我可以使用它

SELECT id, name, GROUP_CONCAT(currency) as currencies GROUP_CONCAT(amount) as amounts 
FROM clients LEFT JOIN currencies ON clients.id = client_id 
WHERE clients.id = 15
GROUP BY clients.id

然后在应用程序级别上事情是如此的棒和漂亮

$results = $stmt->fetchAll();
foreach($results as $k => $v){
    $results[$k]['currencies'] = array_combine(explode(',', $v['currencies']), explode(',', $v['amounts']));
}

我想问的问题是,在性能或任何其他方面使用此功能是否有任何缺点,因为对我来说,它看起来简直太棒了,这让我认为人们一定有理由不使用它经常。

EDIT:

最终,我想问,除了数组覆盖之外,还有哪些其他选项可以从 MySQL 结果集中得到一个多维数组,因为如果我选择 15 列,那么编写这个野兽真的是一个很大的痛苦。


  • 使用 GROUP_CONCAT() 通常会调用分组逻辑并创建临时表,这通常会对性能产生很大的负面影响。有时您可以添加正确的索引来避免在分组查询中使用临时表,但并非在所有情况下都如此。

  • 正如 @MarcB 指出的,组连接字符串的默认长度限制非常短,许多人都对截断的列表感到困惑。您可以增加限制组连接最大长度.

  • 在 PHP 中将字符串分解为数组并不是免费的。仅仅因为您可以在 PHP 中的一个函数调用中完成此操作,并不意味着它是最好的性能。我没有对差异进行基准测试,但我怀疑你也有。

  • GROUP_CONCAT() 是一种 MySQLism。其他 SQL 产品并未广泛支持它。在某些情况下(例如 SQLite),它们有一个 GROUP_CONCAT() 函数,但它的工作方式与 MySQL 中的工作方式并不完全相同,因此如果您必须支持多个 RDBMS 后端,这可能会导致令人困惑的错误。当然,如果你不需要担心移植,这不是问题。

  • 如果您想从您的数据中获取多列currencies表,那么您需要多个 GROUP_CONCAT() 表达式。列表的顺序是否保证相同?也就是说,一个列表中的第三个字段是否对应于下一个列表中的第三个字段?答案是否定的——除非您用ORDER BYGROUP_CONCAT() 内的子句。

我通常喜欢你的第一种代码格式,使用传统的结果集,并循环结果,保存到由客户端 id 索引的新数组,将货币附加到数组。这是一个简单的解决方案,使 SQL 保持简单且更易于优化,并且如果您有多个列要获取,效果会更好。

我并不是想说 GROUP_CONCAT() 不好!在很多情况下它确实很有用。但试图制定任何一刀切的规则来使用(或避免)任何函数或语言功能是过于简单化的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

不使用 GROUP_CONCAT 的原因? 的相关文章

  • posts_search 中的自定义查询

    如何使用此查询作为我的自定义搜索查询 add filter posts search my search is perfect 20 2 function my search is perfect search wp query sWord
  • 从 Getdate() 获取时间

    我想采取Getdate 结果 例如 2011 10 05 11 26 55 000 into 11 26 55 AM 我看过其他地方并发现 Select RIGHT CONVERT VARCHAR GETDATE 100 7 这给了我 11
  • 将“php”作为 shell 脚本执行时的自定义 php.ini 文件

    我在跑php作为 shell 脚本 我不确定 shell脚本 是否正确 该文件以 usr bin php 这很好用 但 MongoDB 类没有正确加载php ini文件 具有extension mongo so 未使用 我该如何使用它tha
  • 为什么我需要结束 ob_start()?

    php 文档建议我应该用 ob end flush 结束每个 ob start 我在网站的每个页面上使用一个 只是为了允许我在应用程序中的任何位置使用 firephp 日志方法 该应用程序运行良好 但我想知道是否有任何我不知道的东西可能有害
  • MYSQL从每个类别中随机选择一条记录

    我有一个数据库Items表看起来像这样 id name category int 有几十万条记录 每个item可以是 7 种不同的之一categories 对应于categories table id category 我想要一个从每个类别
  • 从 .phar 存档中提取文件

    对于 Phar 文件 我完全错过了一些东西 我正在安装一个需要 phpunit pdepend 和其他依赖项的项目 我将它们作为 phar 文件获取 但是 我无法使用命令行工具 php 命令 从中提取文件 我用谷歌搜索了这个问题 但没有发现
  • 为什么 iconv 在 php:7.4-fpm-alpine docker 中返回空字符串

    给出以下代码
  • 使用 SSL 证书验证 Web 浏览器

    是否可以使用 ssl 证书对 Web 浏览器进行身份验证 假设我在应用程序中存储私钥 有什么方法可以从浏览器读取密钥并尝试基于该私钥进行身份验证 您可以使用 SSL TLS 客户端证书身份验证来对浏览器 用户进行身份验证 服务器必须请求客户
  • mysql排序和排名语句

    我需要一些 mysql 语句的帮助 我的表 1 有 7 列 表 2 有 8 列 额外的列名为排名 我的语句应该是这样的 从表 1 中选择全部 然后按 用户数 排序 将其插入表 2 中并排名开始 1 2 3 等 table 1 usernam
  • 通过 $_SESSION 从一个脚本发送到另一个脚本期间数据丢失

    我正在尝试将一个充满属性的对象从一个 PHP 发送到另一个 PHP SESSION object obj where obj是一个用 foreach 循环指定的对象 foreach array of objects as obj SESSI
  • PHP 中只保留数组的前 N ​​个元素? [复制]

    这个问题在这里已经有答案了 有没有办法只保留数组的前 N 个 例如 10 个 元素 我知道有array pop 但是有没有更好 更优雅的方法呢 您可以使用array slice http php net array slice or arr
  • SQL 最近日期

    我需要在 php 中获取诸如 2010 04 27 之类的日期作为字符串 并在表中找到最近的 5 个日期 表中的日期保存为日期类型 您可以使用DATEDIFF http dev mysql com doc refman 5 1 en dat
  • PHP HEREDoc (EOF) 语法在 Sublime Text 3 上突出显示与正斜杠的差异

    我不熟悉 Sublime Text 3 如何使用语法突出显示 例如 如果它纯粹依赖于主题 或者它内置于主题运行的标准中 但就我而言 使用 PHP 的 HERE 文档和转发存在一些语法突出显示差异斜线 一旦出现正斜杠 ST3 就会认为以下所有
  • php 错误 fopen(): 文件名不能为空

    发送带有附件代码的电子邮件工作正常 最近我们已将文件传输到另一个托管服务器 idk 发生了什么 它显示以下错误 警告 fopen 第 106 行 home hugerecruitmetnt public html validatecva p
  • CURL 中的 data-urlencode 是什么意思?

    我搜索了很多个小时试图弄清楚 php curl 中的 data urlencode 是什么 我尝试过这个 但我认为这是不对的 xmlpost object1 file https www lob com goblue pdf 在文档中是 d
  • MySQL 转储未知选项“-no-beep”

    在旧服务器上我使用了mysql转储命令来备份 MySQL 数据库 在新服务器上 MySQL 版本为 5 6 相同的命令给出了错误 unknown option no beep 无论它插入什么 我也在互联网上搜索过 但找不到任何帮助 在 my
  • 一次播种多行 laravel 5

    我目前正在尝试为我的用户表播种 如果我像这样尝试 2 行 就会失败 如果我只使用单个数组而不是 users 数组内的 2 个数组来创建一些假数据 那么效果很好 我做错了什么 正确的方法是什么 class UserTableSeeder ex
  • 对具有混合类型值的数组进行数字排序

    我有一个像这样的混合数组 fruits array lemon Lemon 20 banana apple 121 40 50 然后申请sort 其功能如下 sort fruits SORT NUMERIC foreach fruits a
  • 无法显示 Laravel 欢迎页面

    我的服务器位于 DigitalOcean 云上 我正在使用 Ubuntu 和 Apache Web 服务器 我的家用计算机运行的是 Windows 7 我使用 putty 作为终端 遵循所有指示https laracasts com ser
  • SQL 更新 - 更新选定的行

    我正在使用 SQL Server 2008 我有一个名为MYTABLE有两列 ID STATUS 我想编写一个存储过程来返回其记录STATUS是 0 但是这个存储过程必须更新STATUS返回行数为 1 如何在单个查询中执行此选择和更新操作

随机推荐

  • 当图像接近边缘时,9 块阴影消失

    我正在使用 9 patch 为盒子生成阴影 如果图像宽度为 280dp 距框边缘 20dp 我会得到很好的阴影 315 度 但是 如果我让图像接触框边缘 右边缘的阴影几乎消失 这是我的布局
  • 需要根据 T-SQL 中准入日期列计算出的第一个“3 个月”,为列中的每个值添加 3 个月

    我有 14K 记录表 如下所示 与一个特定 client id 1002 相关的数据示例 我的日期格式是 mm dd yyyy 月份在前 ClientsEpisodes client id adm date disch date 1002
  • Android Fragment 生命周期问题(onActivityResult 上的 NullPointerException)

    我遇到一个问题 我找不到任何解释 我有一个使用 TabManager 显示片段的 FragmentActivity 如下所示 public class WorkOrderFormTabFragmentActivity extends Fra
  • django 更改默认运行服务器端口

    我想设置默认端口manage py runserver侦听无关的指定内容config ini 有没有比解析更简单的修复方法sys argv inside manage py并插入配置的端口 目标是跑 manage py runserver不
  • Wamp 服务器:更改 apache 的 httpd.conf?

    我正在尝试解决我的错误 我无法从服务器连接到我的 Android 应用程序 所有来源都将我引向以下教程作为解决方案 我已成功完成本教程中的所有步骤 除了 编辑Wamp服务器的httpd conf文件 IE 该教程说明了以下内容 4 在htt
  • 如何杀死 goroutine? [复制]

    这个问题在这里已经有答案了 我想知道如何杀死 停止 goroutine 所有示例都基于通道和选择 这似乎只有在 goroutine 包含一些可以在通道上监听的重复任务时才有效 有没有办法在下面的 goroutine 返回之前停止它 pack
  • 使用认知登录而不是证书来验证和订阅 aws IoT MQTT 主题?

    我是 AWS 的新手 我正在尝试弄清楚我的用例是否可行 我想创建一个移动应用程序 用户可以登录 电子邮件 facebook google 等 然后订阅 aws IoT 上的一些 MQTT 主题 以接收园艺系统的实时传感器数据 AWS 上有很
  • 使用循环提取一系列整数

    我有一些数据想要提取整数出现的频率 这是一些示例数据 df lt read table header T text A B C D 1 1 5 3 1 2 1 2 3 2 3 2 3 5 3 4 1 4 5 3 5 3 1 4 2 6 5
  • PostgreSQL 逻辑复制在 CREATE SUBSCRIPTION 上挂起

    我在 PostgreSQL 逻辑复制版本 15 上遇到问题 我也在 v10 和 v12 上进行了测试 但遇到了同样的问题 它需要复制来进行测试 因此源数据库和目标数据库位于同一服务器上 在我设置的配置文件中 postgresql conf
  • 在两个用户控件和主窗体之间传递对象

    因此 我有一个用作导航栏的主窗体和两个显示一些控件的用户控件 In UserControlsA我有一些字段需要填写 使用这些数据 我创建了一个包含一些信息的对象 我需要将该对象传递给UserControlsB所以我可以在那里显示一些数据 我
  • 正则表达式是测试 url 的好方法吗

    我正在尝试测试使用 php5 输入的 url 的有效性 我想过使用正则表达式 但假设它始终正常工作 它只能解决 url 在语法上有效的问题 它没有告诉我有关网址正确或有效的任何信息 如果可能的话 我正在尝试寻找另一种解决方案来同时完成这两件
  • 带参数改造post请求

    我正在使用邮递员扩展来发送请求 我想对 android 提出同样的请求 我使用改造库来实现我的目标 但我无法获得成功的结果 我的代码错误在哪里 Postman 我的界面 public interface Interfacem FormUrl
  • 项目控件将其自身从容器控件中删除

    有一个容器控件 TScrollBox 它是多个项目控件的父控件 每个项目控件本身都是复合的 包含 父级和拥有 一个删除按钮 按下该按钮将启动项目控件的删除 删除涉及释放组件 因此实际操作应该与该项目无关 问题是 最好的方法是什么 我实际上知
  • OCaml 与非常量的模式匹配

    是否可以对变量而不是常量值进行模式匹配 let x 2 in let y 5 in match 2 with x gt foo y gt bar gt baz let y 5 in Warning 26 unused variable y
  • 如何在导出xml中添加DOCTYPE?

    我使用 PHP 导出了一个 xml 文件 xmldoc new DOMDocument xmldoc gt formatOutput true xmldoc gt encoding Shift JIS create root nodes r
  • 与Subject在组件之间共享数据

    我正在尝试在 Angular 6 中的两个组件之间与主题共享数据 不知怎的 它不起作用 我不知道为什么 我需要通过单击将数据从compare component 传递到profile component 当我点击时 数据没有传递 但不知怎的
  • EOFError:读取一行时出现EOF

    我正在尝试定义一个函数来制作矩形的周长 这是代码 width input height input def rectanglePerimeter width height return width height 2 print rectan
  • 如何用java在现有PDF中添加空白页? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我有普通的 PDF 文件 我想使用在 PDF 末尾插入空白页itext LIBRARY
  • 如何使用 HTML/JavaScript 捕获客户端“桌面”部分的屏幕截图?

    我知道如何捕获网页 但我想问如何捕获桌面或桌面中的其他应用程序 如果有办法突出显示屏幕的某些部分 就像 html2canvas 对网页所做的那样 我们可以使用 HTML JS 中的浏览器应用程序为桌面应用程序做一些事情吗 对的 这是可能的
  • 不使用 GROUP_CONCAT 的原因?

    我刚刚发现了这个非常有用的 MySQL 函数GROUP CONCAT 它对我来说似乎非常有用并且过于简单化 以至于我实际上害怕使用它 主要是因为我开始网络编程已经有一段时间了 而且我从未在任何地方见过它 一个很棒的用法示例如下 Table