MySQL LEFT JOIN json 字段与表中的另一个 id
Posted
技术标签:
【中文标题】MySQL LEFT JOIN json 字段与表中的另一个 id【英文标题】:MySQL LEFT JOIN json field with another id from table 【发布时间】:2017-10-15 14:56:47 【问题描述】:我有两张桌子:
Bouquets
+----+------------+
| id | bouquet |
+----+------------+
| 1 | Package #1 |
| 2 | Package #2 |
| 3 | Package #3 |
| 4 | Package #4 |
| 5 | Package #5 |
+----+------------+
和
Prices
+----+----------+-------------------------------------------------------------------+
| id | reseller | price
+----+----------+-------------------------------------------------------------------+
| 1 | 1 | "1": "1.11", "2": "0.00", "3": "0.00", "4": "4.44", "5": "5.55" |
+----+----------+-------------------------------------------------------------------+
我需要获取价格值不是“0.00”的花束名称...所以我尝试 LEFT JOIN 在价格上加入花束.id 但我不知道怎么做?
我需要得到这个:
+----+------------+
| id | bouquet |
+----+------------+
| 1 | Package #1 |
| 4 | Package #4 |
| 5 | Package #5 |
+----+------------+
这是我的尝试,但我得到的是空结果:
SELECT b.id, b.bouquet FROM bouquets b
LEFT JOIN prices p ON JSON_CONTAINS(p.price, CAST(b.id as JSON), '$') != "0.00"
WHERE p.reseller=1;
【问题讨论】:
JSON_CONTAINS 不会遍历所有键来寻找“0.0”的值。您可以对每个键执行类似 test JSON_CONTAINS(price,'"2" : "0.00"') FROM price 的操作。在这种情况下,您可能应该考虑使用关系模型来轻松操作,而不是将所有内容都塞入 JSON 列 好的,您能否发布在 p.price id 上 LEFT JOIN b.id 的示例代码?例如 b.id = 1 ON p.price = "1" 并读取 "1" = "1.11" 的值,这样我就可以做 > "0.00" 【参考方案1】:我正在使用 mysql 包装器在节点 js 中编程,这是我使用的解决方案,它正在工作:
/* QUERY - aaBouquets */
connection.query("SELECT id, bouquet FROM bouquets ORDER BY bouquet ASC",function(err, rows, fields)
/* BOUQUETS - number */
var total = rows.length;
/* FOUND - bouquets */
if (rows.length)
/* GET - prices */
for (var i in rows)
var s = 1;
connection.query("SELECT '"+rows[i].id+"' AS id, '"+rows[i].bouquet+"' AS bouquet FROM prices p LEFT JOIN bouquets b ON JSON_SEARCH(p.price, 'one', '$.\""+rows[i].id+"\"') WHERE p.reseller=? AND FORMAT(JSON_EXTRACT(price, '$.\""+rows[i].id+"\"'), 2) != \"0.00\"",[qreseller], function(err, rows, results)
/* CHECK - prices */
if (s < total)
if (rows.length)
/* GET - prices */
data.push(rows[0]);
;
s++;
else
/* CHECK - prices */
if(data.length)
if (rows.length)
/* GET - prices */
data.push(rows[0]);
;
/* RETURN - servers data */
res.json(data);
;
);
);
您可以看到第一个查询正在获取 id 和花束名称,然后在 for 循环中我使用该 id 获取该花束 id 的值,并且仅当值不等于“0.00”时才显示......使用变量 s 和总计在这里,因为如果我调用 console.log(data) 我得到未定义的变量..因为节点中的 js 变量是本地的,如果在外部调用,则需要在 for 循环内调用,我得到未定义的变量错误。
这种方式我只得到具有定义价格的花束......我不知道它是否可以在单个查询中完成(因为你不能在 p.prices 上使用 LEFT JOIN ON b.id)所以需要这个两个查询...对我来说一切正常...所以如果有人可以最小化代码以使其更快或改进...欢迎。
【讨论】:
【参考方案2】:这似乎并不容易在 mysql 中完成,最好的办法是使用(php、ASP 等)来完成繁重的工作,但经过大量试验和错误后,我发现了这篇文章:
Convert JSON array in MySQL to rows
从那里这个查询似乎对我有用
SELECT
b.id,
b.bouquet
FROM bouquet AS b
JOIN (
SELECT
indx.id,
indx.idx,
JSON_EXTRACT(p.price, idx) AS bouquetprice
FROM prices AS p
JOIN (
SELECT '$."1"' AS idx, 1 AS id UNION
SELECT '$."2"' AS idx, 2 AS id UNION
SELECT '$."3"' AS idx, 3 AS id UNION
SELECT '$."4"' AS idx, 4 AS id UNION
SELECT '$."5"' AS idx, 5 AS id
) AS indx
WHERE JSON_EXTRACT(p.price, idx) IS NOT NULL
AND p.reseller = 1
) AS ind
ON b.id = ind.id
AND ind.bouquetprice != "0.00"
诀窍似乎是链接的 SO 帖子中的 CONCAT 不适用于您的 json 中的数字键名称。因此,您必须借助临时连接中的 2 个索引进行搜索。
此外,临时连接表在创建不断增长的索引列表方面并不理想,但它至少是一个开始的地方。 (对不起所有不好的命名 idx、indx 等)
编辑:忘记reseller
部分
【讨论】:
谢谢...我得到了类似的解决方案..请检查上面...这是很好的语法代码和想法我喜欢它...谢谢【参考方案3】:称我为老式,但我真的不喜欢存储 json 数据。无论如何,一个规范化的表可能看起来像这样......
Prices
+----------+------------+-------+
| reseller | bouquet_id | price |
+----------+------------+-------+
| 1 | 1 | 1.11 |
| 1 | 4 | 4.44 |
| 1 | 5 | 5.55 |
+----------+------------+-------+
【讨论】:
我知道..但是如果我假设每个经销商有 100 个经销商和 20bouquet_id,那么我将在 mysql 表中拥有 100x20=2000 条记录......所以我会留在 json 中,这更容易但我不知道如何离开...谢谢你的想法以上是关于MySQL LEFT JOIN json 字段与表中的另一个 id的主要内容,如果未能解决你的问题,请参考以下文章
mysql left join,right join,inner join的区别
Mysql之inner join,left join,right join详解