如何在 SQL 子查询中获取字符串数组

Posted

技术标签:

【中文标题】如何在 SQL 子查询中获取字符串数组【英文标题】:How to get a string array in SQL subqueries 【发布时间】:2021-10-14 08:43:23 【问题描述】:

我正在寻找从不同表返回多个数据的 SQL 查询。

这是一个例子:

SELECT 
    product.*,
    (SELECT category_name FROM category 
     WHERE product.category_id = category_id) AS category_name
FROM 
    product_table AS product
WHERE 
    product.id = 17

此请求将完美运行,但我需要第二个子查询:

(SELECT category_name FROM category 
 WHERE product.category_id = category_id) AS category_name

返回 category_table 并将所有列转换为字符串数组,这样我就可以在 php 中explode(',', $category_name)。

所以换句话说,我试图在另一个表中检索一个表,而这在 SQL 中是不可能的。我想将category_table中的行转换为字符串数组,然后在PHP中将其转换回真正的数组。

预期结果:

ProductObject 
id => 1,
name => "Product Name",
category => "[id, category_name, category_description]" # It also be a json

预期的解决方案类型:

(SELECT TO_STRING_ARRAY(*) FROM category 
 WHERE product.category_id = category_id) AS category_table

其中 TO_ARRAY(不存在)是将行转换为字符串数组的 SQL 函数。

这也可能是一个非常有用的解决方案,因为我们可以通过这个在一个 SQL 查询中获取表中的表(嵌套表)。

【问题讨论】:

查找GROUP_CONCAT()。如果您需要嵌套表格,那么我通常会这样做,将表格转换为 XML。 我现在很想写这个(但不起作用)` SELECT product.*, (SELECT GROUP_CONCAT(*) FROM category WHERE product.category_id = category.id) AS category_name FROM product_table AS product WHERE product.id = 17 ` 如果有办法自动连接所有列,那就太好了。 GROUP_CONCAT() 用于单个字段(或首先与 CONCAT 连接的字段) 【参考方案1】:

使用CONCAT+分隔符,但是如果你的列值包含分隔符会有问题

SELECT a.*, CONCAT(b.category_id, ',', b.category_name, ',', b.category_description) AS cat_info
FROM product_table a 
LEFT JOIN category b ON a.category_id = b.category_id
WHERE a.id = 17

或使用JSON_ARRAY

SELECT a.*, JSON_ARRAY(b.category_id, b.category_name, b.category_description) AS cat_info
FROM product_table a 
LEFT JOIN category b ON a.category_id = b.category_id
WHERE a.id = 17

【讨论】:

这个答案帮助我找到了一个好的解决方法! JSON_OBJECT('id', 17, 'name', category.name)。我将向自己发布一个答案作为部分解决方案【参考方案2】:

作为一个非常有效的部分解决方案 但可以改进为自动将每个列名称作为键

感谢@progu,我使用 JSON_ARRAY 进行了一些搜索,发现 JSON_OBJECT 更适合我的需求。

部分解决方案:

SELECT 
 p.*, 
 (SELECT JSON_OBJECT(
     "id", category.id,
     "name", category.name,
     "description", category.description
 ) FROM category WHERE p.category_id = category.id ) AS _category,
FROM product_table p
WHERE p.id = 17

JSON_OBJECT 在我的情况下效果很好,因为我也需要“密钥”。 JSON_ARRAY 在某些情况下可以工作,但我使用函数在 PHP 中从 json 字符串构建对象(键对于正确的对象属性识别很重要)。

所以使用 JSON_OBJECT 我可以简单地做一个 json_decode 并且我有一个对象。


有没有办法自动获取每个列的名称?

所以我不需要一直手动输入:

JSON_OBJECT(
    THIS => "id", 
        category.id,
    THIS => "name", 
        category.name,
    THIS => "description", 
        category.description
)

因为 JSON_OBJECT('key_1', 'value_of_key_1', 'key_2', 'value_of_key_2') 就是这样工作的。

谢谢大家

【讨论】:

以上是关于如何在 SQL 子查询中获取字符串数组的主要内容,如果未能解决你的问题,请参考以下文章

在SQL中如何从数组中获取值再进行查询

将 wpdb sql 数组转换为 php 数组

如何从字符串中获取子字符串并将另一个字符串附加到字符串并将其转换为数组

怎样将数组作为Sql中IN的查询条件

PHP如何将SQL查询结果转为多维数组,并按查询行输出

在 Presto 中,如何检查我通过子查询获取的列表中是不是存在数组中的元素