草庐IT

php - mySQL:将一列的结果作为多列返回

coder 2023-10-22 原文

第一次在这里提问,如果格式不正确,敬请谅解。

我正在尝试从多个表中提取一些信息以构建报告。所述表格来自 Magento 实例,以防有帮助。

所以,我有四个正在使用的表: customer_entity、customer_address_entity、customer_address_entity_textcustomer_address_var_char

customer_entity中,我需要获取三个字段:entity_id、email和group_id

customer_address_entity 中,我需要获取 parent_id(等于上面的 entity_id)和 entity_id(与上面的不同)。

customer_address_entity_text 中,我需要 entity_id、attribute_id 和值。

customer_address_entity_varchar 中,我需要值、entity_id 和 attribute_id。

我的问题主要在于最后一张表。我需要获取六个属性 ID 的值,但我希望将值作为多列(名字、姓氏、电子邮件等)而不是仅作为值返回。

这是我当前的代码:

SELECT
customer_entity.entity_id as "Customer ID", email, customer_address_entity_text.value as "Street Address", customer_address_entity_varchar.value
FROM
customer_entity, customer_address_entity, customer_address_entity_text, customer_address_entity_varchar
WHERE
customer_entity.group_id="2"
AND
customer_entity.entity_id = customer_address_entity.parent_id
AND
customer_address_entity.entity_id = customer_address_entity_text.entity_id
AND
customer_address_entity_text.attribute_id="24"
AND
customer_address_entity.entity_id = customer_address_entity_varchar.entity_id
AND
customer_address_entity_varchar.attribute_id in (19,21,25,26,27)

返回的结果格式如下:

Current

我想要的是:

Desired

是的,列顺序不是最好的,但我会在根据需要对列进行格式化后处理它。我尝试了几个子字符串查询(其中一个最终使服务器崩溃;哎呀)并使用了 EXISTS。是的,我的代码也很丑陋;我计划在获得所需格式的数据后清理它。

谢谢!

编辑:如果有人想要一份我最终部署的代码副本(向 Bernd 致敬):

SELECT
e.entity_id as "Customer ID", e.email, t.value AS "Street Address",
GROUP_CONCAT(IF(v.attribute_id = 19,v.value,NULL)) AS "First Name",
GROUP_CONCAT(IF(v.attribute_id = 21,v.value,NULL)) AS "Last Name",
GROUP_CONCAT(IF(v.attribute_id = 25,v.value,NULL)) AS "City",
GROUP_CONCAT(IF(v.attribute_id = 27,v.value,NULL)) AS "Region/State",
GROUP_CONCAT(IF(v.attribute_id = 26,v.value,NULL)) AS "Country"
FROM customer_entity e 
LEFT JOIN customer_address_entity a ON a.parent_id = e.entity_id
LEFT JOIN customer_address_entity_varchar v ON v.entity_id = a.entity_id
LEFT JOIN customer_address_entity_text t on t.entity_id = a.entity_id
WHERE e.group_id = 2
AND t.attribute_id = 24
GROUP BY v.entity_id

最佳答案

不必多次加入表。您可以对结果进行分组并获得值。这是一个示例

两个表

MariaDB [tmp]> select *from names;
+----+-------+----------------+
| id | name  | email          |
+----+-------+----------------+
|  1 | Bernd | bernd@bernd.de |
|  2 | David | david@david.de |
+----+-------+----------------+
2 rows in set (0.00 sec)

MariaDB [tmp]> select * from customer_address_entity;
+-----------+--------------+------------------+
| entity_id | attribute_id | value            |
+-----------+--------------+------------------+
|         1 |            1 | Duesseldorf      |
|         1 |            2 | 40211            |
|         1 |            3 | berlinerplatz 55 |
|         1 |            4 | 0211 / 1234567   |
|         2 |            1 | Bremen           |
|         2 |            2 | 21334            |
|         2 |            3 | Aachenerstr. 99  |
|         2 |            4 | 0432 / 7890111   |
+-----------+--------------+------------------+
8 rows in set (0.00 sec)

加入表

MariaDB [tmp]> SELECT
    ->   n.*,a.*
    -> FROM `names` n
    -> LEFT JOIN customer_address_entity a ON a.entity_id = n.id;
+----+-------+----------------+-----------+--------------+------------------+
| id | name  | email          | entity_id | attribute_id | value            |
+----+-------+----------------+-----------+--------------+------------------+
|  1 | Bernd | bernd@bernd.de |         1 |            1 | Duesseldorf      |
|  1 | Bernd | bernd@bernd.de |         1 |            2 | 40211            |
|  1 | Bernd | bernd@bernd.de |         1 |            3 | berlinerplatz 55 |
|  1 | Bernd | bernd@bernd.de |         1 |            4 | 0211 / 1234567   |
|  2 | David | david@david.de |         2 |            1 | Bremen           |
|  2 | David | david@david.de |         2 |            2 | 21334            |
|  2 | David | david@david.de |         2 |            3 | Aachenerstr. 99  |
|  2 | David | david@david.de |         2 |            4 | 0432 / 7890111   |
+----+-------+----------------+-----------+--------------+------------------+
8 rows in set (0.00 sec)

对其进行分组并获取字段

MariaDB [tmp]> SELECT
    ->   n.name, n.email,
    ->   GROUP_CONCAT( IF ( a.attribute_id = 1 , a.value,NULL)) AS city,
    ->   GROUP_CONCAT( IF ( a.attribute_id = 2 , a.value,NULL)) AS plz,
    ->   GROUP_CONCAT( IF ( a.attribute_id = 3 , a.value,NULL)) AS street,
    ->   GROUP_CONCAT( IF ( a.attribute_id = 4 , a.value,NULL)) AS phone
    -> FROM `names` n
    -> LEFT JOIN customer_address_entity a ON a.entity_id = n.id
    -> GROUP BY a.entity_id;
+-------+----------------+-------------+-------+------------------+----------------+
| name  | email          | city        | plz   | street           | phone          |
+-------+----------------+-------------+-------+------------------+----------------+
| Bernd | bernd@bernd.de | Duesseldorf | 40211 | berlinerplatz 55 | 0211 / 1234567 |
| David | david@david.de | Bremen      | 21334 | Aachenerstr. 99  | 0432 / 7890111 |
+-------+----------------+-------------+-------+------------------+----------------+
2 rows in set (0.00 sec)

MariaDB [tmp]>

关于php - mySQL:将一列的结果作为多列返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32999059/

有关php - mySQL:将一列的结果作为多列返回的更多相关文章

  1. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  2. ruby - RSpec - 使用测试替身作为 block 参数 - 2

    我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere

  3. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

  4. ruby - Ruby 中的隐式返回值是怎么回事? - 2

    所以我开始关注ruby​​,很多东西看起来不错,但我对隐式return语句很反感。我理解默认情况下让所有内容返回self或nil但不是语句的最后一个值。对我来说,它看起来非常脆弱(尤其是)如果你正在使用一个不打算返回某些东西的方法(尤其是一个改变状态/破坏性方法的函数!),其他人可能最终依赖于一个返回对方法的目的并不重要,并且有很大的改变机会。隐式返回有什么意义?有没有办法让事情变得更简单?总是有返回以防止隐含返回被认为是好的做法吗?我是不是太担心这个了?附言当人们想要从方法中返回特定的东西时,他们是否经常使用隐式返回,这不是让你组中的其他人更容易破坏彼此的代码吗?当然,记录一切并给出

  5. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

  6. ruby-on-rails - 使用 ruby​​ 将多个实例变量转换为散列的更好方法? - 2

    我收到格式为的回复#我需要将其转换为哈希值(针对活跃商家)。目前我正在遍历变量并执行此操作:response.instance_variables.eachdo|r|my_hash.merge!(r.to_s.delete("@").intern=>response.instance_eval(r.to_s.delete("@")))end这有效,它将生成{:first="charlie",:last=>"kelly"},但它似乎有点hacky和不稳定。有更好的方法吗?编辑:我刚刚意识到我可以使用instance_variable_get作为该等式的第二部分,但这仍然是主要问题。

  7. ruby-on-rails - ruby 日期方程不返回预期的真值 - 2

    为什么以下不同?Time.now.end_of_day==Time.now.end_of_day-0.days#falseTime.now.end_of_day.to_s==Time.now.end_of_day-0.days.to_s#true 最佳答案 因为纳秒数不同:ruby-1.9.2-p180:014>(Time.now.end_of_day-0.days).nsec=>999999000ruby-1.9.2-p180:015>Time.now.end_of_day.nsec=>999999998

  8. ruby - 从 String#split 返回的零长度字符串 - 2

    在Ruby1.9.3(可能还有更早的版本,不确定)中,我试图弄清楚为什么Ruby的String#split方法会给我某些结果。我得到的结果似乎与我的预期相反。这是一个例子:"abcabc".split("b")#=>["a","ca","c"]"abcabc".split("a")#=>["","bc","bc"]"abcabc".split("c")#=>["ab","ab"]在这里,第一个示例返回的正是我所期望的。但在第二个示例中,我很困惑为什么#split返回零长度字符串作为返回数组的第一个值。这是什么原因呢?这是我所期望的:"abcabc".split("a")#=>["bc"

  9. 报告回顾丨模型进化狂飙,DetectGPT能否识别最新模型生成结果? - 2

    导读语言模型给我们的生产生活带来了极大便利,但同时不少人也利用他们从事作弊工作。如何规避这些难辨真伪的文字所产生的负面影响也成为一大难题。在3月9日智源Live第33期活动「DetectGPT:判断文本是否为机器生成的工具」中,主讲人Eric为我们讲解了DetectGPT工作背后的思路——一种基于概率曲率检测的用于检测模型生成文本的工具,它可以帮助我们更好地分辨文章的来源和可信度,对保护信息真实、防止欺诈等方面具有重要意义。本次报告主要围绕其功能,实现和效果等展开。(文末点击“阅读原文”,查看活动回放。)Ericmitchell斯坦福大学计算机系四年级博士生,由ChelseaFinn和Chri

  10. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

随机推荐