PHP-MySQL EAV SELECT一对多单行结果
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了PHP-MySQL EAV SELECT一对多单行结果,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3488字,纯文字阅读大概需要5分钟。
内容图文
![PHP-MySQL EAV SELECT一对多单行结果](/upload/InfoBanner/zyjiaocheng/882/75c2f126a0d5480fbc03e1df6553a06e.jpg)
我在这里看到过类似的问题,但是找不到与我的特定情况相匹配的问题.我有以下三个表:
content
id, [other fields]
attributes
id, title
attributes_values
id, attribute_id[foreign to attributes.id], content_id[foreign to content.id], value
我想要的是一个单一查询(或子查询组),该查询可以返回适当的数据,而不必在编程中操纵它.
有关表的更多信息:属性具有三个记录(模型编号,零件编号和购物车中的显示).
我需要从内容中选择其中在购物车中显示= 1的attribute_value的所有记录.与此同时,我希望其他相关的attribute_values作为其相关的attribute.title返回.结果看起来像这样:
id [other fields] Model # [from attributes.title field] Part # [from attributes.title field]
1 [any data] value from attributes_values value from attributes_values
2 [any data] value from attributes_values value from attributes_value
到目前为止,我完成此操作的唯一方法不是很优雅,因为我必须对同一张表进行多次连接:
SELECT * FROM content AS a
LEFT JOIN attributes_values AS b ON (b.content_id = a.id AND b.attribute_id = [Model # ID])
LEFT JOIN attributes_values AS c ON (c.content_id = a.id AND c.attribute_id = [Part # ID])
WHERE a.id IN (
SELECT content_id FROM attributes_values WHERE attribute_id = [Show in Cart ID] AND value = 1
)
如您所见,我必须将相关的键硬编码到JOIN语句中,但这并不能使其具有很好的可伸缩性(并且感觉很脏).
最后几点注意事项:我正在使用PHP和Joomla !,因此,如果这会影响您的答案(或者有一些秘密的Joomla技巧),请随时添加.另外,这是我无法更改的预先建立的表架构,因此我需要针对上述表的查询解决方案,而不是对更好的表设计的建议.
任何帮助将不胜感激.
干杯!
解决方法:
您可以将诸如MAX()之类的聚合函数与CASE WHEN语句结合使用,而不是为每个属性多次联接表:
SELECT
content.id,
[other_fields],
MAX(CASE WHEN attributes.title='Model #' THEN attributes_values.value END) AS Model_N,
MAX(CASE WHEN attributes.title='Part #' THEN attributes_values.value END) AS Part_N
FROM
content INNER JOIN attributes_values
ON content.id = attributes_values.content_id
INNER JOIN attributes
ON attributes_values.attribute_id = attributes.id
GROUP BY
id,
[other_fields]
HAVING
MAX(CASE WHEN attributes.title='Show in Cart' THEN attribute_values.value END)='1'
一点解释:
CASE WHEN attributes.title='Model #' THEN attributes.value END
当属性为’Model#’时将返回值,否则为NULL,并且
MAX(...)
将返回最大非NULL值,该值是attribute.title =’Model#’的值.
动态属性
MySQL没有Pivot函数,因此,如果您希望列表是动态的,则必须动态创建一个具有所有属性的SQL字符串并执行该字符串.
您可以从属性表中获取所有属性:
SELECT
CONCAT(
'MAX(CASE WHEN attributes.title=''',
REPLACE(attributes.title, '''', ''''''),
''' THEN attributes_values.value END) AS `',
REPLACE(attributes.title, '`', '``'),
'`'
)
FROM
attributes;
并将所有内容与GROUP_CONCAT结合在一起:
SELECT GROUP_CONCAT(...the concat above...)
FROM attributes;
因此您的最终查询将如下所示:
SELECT
CONCAT('SELECT content.id,',
GROUP_CONCAT(
CONCAT(
'MAX(CASE WHEN attributes.title=''',
REPLACE(attributes.title, '''', ''''''),
''' THEN attributes_values.value END) AS `',
REPLACE(attributes.title, '`', '``'),
'`'
)
),
' FROM content INNER JOIN attributes_values ',
'ON content.id = attributes_values.content_id ',
'INNER JOIN attributes ',
'ON attributes_values.attribute_id = attributes.id ',
'GROUP BY id HAVING ',
'MAX(CASE WHEN attributes.title=''Show in Cart'' THEN attributes_values.value END)=''1'''
)
FROM
attributes
INTO @SQL;
现在,@ SQL变量将保存要执行的查询的值,您可以使用以下命令执行它:
PREPARE stmt FROM @sql;
EXECUTE stmt;
唯一的问题是GROUP_CONCAT的值为maximum length limit,如果表中包含许多属性,则可以增加它.
请参见小提琴here的示例.
内容总结
以上是互联网集市为您收集整理的PHP-MySQL EAV SELECT一对多单行结果全部内容,希望文章能够帮你解决PHP-MySQL EAV SELECT一对多单行结果所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。