我有一个基于关系MySQL数据库的系统,允许人们存储“潜在客户”的详细信息。此外,人们可以创建自己的列来存储数据,然后在添加新帐户时可以在其下添加数据。表结构如下所示:
LEADS - ID, 电子邮件, USER_ID
属性 - ID, attr_name, USER_ID
ATTR_VALUES - lead_id, attr_id, 值, USER_ID
显然,在这些表中,“user_id”指的是“用户”表,其中只包含可以登录系统的人员。
我正在编写一个函数来输出引导细节,目前我只是将基本的引导细节作为查询,然后拉出与该引导关联的每个属性值(连接属性表以获取名称)然后在PHP中加入数组。这有点乱,我想知道是否有办法在一个SQL查询中执行此操作。我已经阅读了一些关于“数据透视表”的内容,但我很难理解它是如何工作的。
非常感谢任何帮助。谢谢!
答案 0 :(得分:1)
您可以在单个查询中进行透视,如下所示:
select l.id lead_id,
l.email,
group_concat(distinct case when a.attr_name = 'Home Phone' then v.value end) HomePhone,
...
from leads l
left join attr_values v on l.id = v.lead_id
left join attributes a on v.attr_id = a.id
group by l.id
您需要为要显示的每个属性添加单独的group_concat
派生字段。
答案 1 :(得分:0)
我会看看这个link。这解释了枢轴的基本原理:
“数据透视表”或“交叉表报表”SQL特性函数:执行 它没有“if”,“case”或“GROUP_CONCAT”。是的,有用 这......“if”语句在使用时有时会引起问题 组合。简单的秘密,这也是他们几乎工作的原因 所有数据库,都是以下函数:sign(x)返回-1,0,+ 1 对于值x&lt; 0,x = 0,x> 0分别为abs(sign(x))返回0 if x = 0 else,1 if x&gt; 0或x <0 0 1-abs(符号(x))补码 上面,因为只有当x = 0
时才返回1
它还解释了一种更简单的旋转考试方式。也许这可以为它提供一些启示?
答案 2 :(得分:0)
您可能希望从mysql中获取一个sql值(在您的情况下为attr_name
)一列。这个原则称为pivot table(有时也是交叉表或交叉表查询),mysql不支持。不是因为mysql不够,而是因为数据透视操作不是数据库操作 - 结果不是普通的数据库表,并且不设计用于进一步的数据库操作。 透视操作演示的唯一目的 - 这就是它属于表示层而不是数据库的原因。
因此,尝试从mysql获取数据透视表的每个解决方案都将是hacky。我建议的是以正常格式从数据库中获取数据,只需执行以下操作:
select *
from attr_values join attributes using on attr_id = attributes.id
join leads on leads.id = lead_id
然后以表示语言(PHP,JSP,Python或其他任何使用的方式)转换数据库输出。
答案 3 :(得分:0)
我会小心地假设枢轴将实现您的简化目标。只有当attr_name一致时,Pivot才会起作用。由于您将用户标识绑定到它,我认为它不会。此外,您将为一个attr_name设置多个值。我担心数据透视表不会产生您正在寻找的结果。
我建议您将事务和报表分开。有一个ETL例程将通过转换来清除(即使attr_name和attr_value)一致。这将使您的报告更有意义。
总之,对于最终用户的即时输出,PHP是您可以做的最好的。对于报告,在尝试报告之前,首先将EAV转换为行/列。