Php SQL连接-需要单行

Php SQL连接-需要单行,php,sql,join,left-join,Php,Sql,Join,Left Join,My MySQL表结构由两个类似于以下内容的表组成: UserId field1 field2 1 XXX YYY 2 ABC DDD 3 EEE FFF . . . n GGG DDD UserId attribute 1 blah 1 adfadf 1 ddad 2 adff 3 adfa 3 sdff . . . z

My MySQL表结构由两个类似于以下内容的表组成:

UserId field1 field2
1       XXX    YYY
2       ABC    DDD
3       EEE    FFF
.
.
.
n       GGG    DDD


UserId  attribute
1        blah
1        adfadf 
1        ddad
2        adff
3        adfa
3        sdff
.
.
.
z        adss
SELECT
    t1.`UserId`,
    t1.`field1`,
    t1.`field2`,
    t2.`attribute`
FROM `table1` AS `t1`
    LEFT JOIN `table2` AS `t2` ON `t1`.UserId = `t2`.UserId
WHERE t1.`UserId` = 3
3 EEE FFF adfa
3 EEE FFF sdff
表1每个ID只有一条记录。表2每个ID有M条记录。表1和表2中的ID是相关的。我的查询类似于以下内容:

UserId field1 field2
1       XXX    YYY
2       ABC    DDD
3       EEE    FFF
.
.
.
n       GGG    DDD


UserId  attribute
1        blah
1        adfadf 
1        ddad
2        adff
3        adfa
3        sdff
.
.
.
z        adss
SELECT
    t1.`UserId`,
    t1.`field1`,
    t1.`field2`,
    t2.`attribute`
FROM `table1` AS `t1`
    LEFT JOIN `table2` AS `t2` ON `t1`.UserId = `t2`.UserId
WHERE t1.`UserId` = 3
3 EEE FFF adfa
3 EEE FFF sdff
查询将返回以下内容:

UserId field1 field2
1       XXX    YYY
2       ABC    DDD
3       EEE    FFF
.
.
.
n       GGG    DDD


UserId  attribute
1        blah
1        adfadf 
1        ddad
2        adff
3        adfa
3        sdff
.
.
.
z        adss
SELECT
    t1.`UserId`,
    t1.`field1`,
    t1.`field2`,
    t2.`attribute`
FROM `table1` AS `t1`
    LEFT JOIN `table2` AS `t2` ON `t1`.UserId = `t2`.UserId
WHERE t1.`UserId` = 3
3 EEE FFF adfa
3 EEE FFF sdff
我不想每次都返回重复的记录。我想返回一行,类似于

3 EEE FFF (adfa,sdff)
其中第四个字段是一个数据结构(数组?结果集?),它包含为给定用户ID返回的所有属性

编辑:::
我看到许多涉及CONCAT的解决方案,将其转化为CSV。有逗号的字段可能会把事情搞砸吗?

不确定这是否适用于您的SQL变体。在T-SQL中,这可以通过引入局部变量来实现。这个小例子说明了这一点。如果您不熟悉,“WITH”子句是一个“公共表表达式”,它很容易为我提供示例数据

declare @temp as varchar(10);
select @temp = '';

with vals as (
    select '1' as a
    union select '2' as a
)
select @temp = @temp +  a + ','
from vals

select '(' + @temp + ')'

对于您的查询,只需将其更改为
选择@temp=@temp+属性
。当然,您需要添加一些子字符串代码来删除最后一个多余的逗号。

如果您使用的是mysql,一种方法是使用。如果您使用mysql,请尝试。如果适合,请注意,组_CONCAT有一个最大长度。您可以使用会话变量“group\u concat\u max\u len”调整该值。

您需要使用group\u concat操作符执行连接和分组:

SELECT t1.`UserId`, t1.`field1`, t1.`field2`,
       concat('(', group_concat(t2.`attribute`, ','), ')')
FROM `table1` `t1` LEFT JOIN
     `table2` AS `t2`
     ON `t1`.UserId = `t2`.UserId
WHERE t1.`UserId` = 3 
group by t1.`UserId`, t1.`field1`, t1.`field2`

我的评论摘要:


单个字段中唯一可以存在的数据结构是基元数据类型

在这种情况下,使用逗号分隔的字符串是有意义的。不能在其中放置数组,也不能在其中嵌套数据集。关系数据库通过多行数据实现了您想要的功能,正如您已经拥有的一样。在关系数据库中,将多个值聚合到单个字段被认为是一种非常痛苦的反模式。用这么多不同的方式查询数据会让人感到痛苦

简言之:

  • 单独行上的单独值=
    良好
  • 将值合并到单个字段=
    错误
当前的结构是关系数据库中正常的最佳实践,我永远不会推荐JSON_编码的字符串选项。我的建议是完全不要这样做,除非你有特殊的理由需要这样做。如果你有一个我很想知道它,因为我们可以评论这个方法是否真的有用。通常情况下,试着按照你的要求去做从长远来看是没有帮助的

根据您的示例,如果您有两个已经包含逗号的值,会发生什么情况?这只是自找麻烦



如果您确实担心不必要的网络流量,请分别从两个表中选择,并在嵌套循环中处理它们*(只需确保两个数据集的排序方式相同[在本例中按用户id排序],以使嵌套循环尽可能简单。)*

您使用的是什么RDBMS?MySQL?抱歉,忘了提及。MySQL单个字段中唯一可以存在的数据结构是基元数据类型。在这种情况下,使用逗号分隔的字符串是有意义的。不能在其中放置数组,也不能在其中嵌套数据集。关系数据库通过多行数据实现了您想要的功能,正如您已经拥有的一样。在关系数据库中,将多个值聚合到单个字段被认为是一种非常痛苦的反模式。用这么多不同的方式查询数据会让人感到痛苦。如果我可以问你,为什么你需要把所有的东西聚合成一行?@user974896-我想我可能还不清楚。单独行上的单独值=
良好
。将值合并到单个字段=
错误
。当前的结构是关系数据库中正常的最佳实践,我永远不会推荐JSON_编码的字符串选项。我的建议是完全不要这样做,除非你有特殊的理由需要这样做。如果你有一个我很想知道它,因为我们可以评论这个方法是否真的有用。从长远来看,通常尝试执行您要求的操作是没有帮助的。@user974896-将带有逗号的值聚合到逗号分隔的列表中只是一个例子,说明了为什么我会说您不应该这样做。不幸的是,OP在您写此答案时提到这是MySQL。很抱歉,回复太晚了。至于JSON_编码是件好事,我想到了一个例子。对于我不久前做的一个webapp(api),我需要存储最近10个浏览该配置文件的访问者。我只需拉取并对对象进行JSON_解码,然后将其转换为滚动队列。我将排队\d查询并更新。当出于某种原因需要存储数组并保留顺序时,也可以使用。非常简单,我不需要做任何复杂的逻辑。我还保存了几个查询。事实上,我知道我不必对这些字段进行反向查找。