这是Insert into a MySQL table or update if exists的延续,但这次我想更新mysql中的json条目
以下是架构:
CREATE TABLE TAG_COUNTER (
account varchar(36) NOT NULL,
time_id INT NOT NULL,
counters JSON,
PRIMARY KEY (account, time_id)
)
示例数据如下所示。
"google", "20180510", "{"gmail_page_viewed" : 12000300, "search_page_viewed" : 9898884726423}"
实际上我总是希望更新(递增计数器)此表。但每天开始time_id(yyyyMMdd)是新的,因此计数器json没有计数器键(例如gmail_page_viewed
)。
所以我想要的解决方案是在不存在的情况下创建新的json键列,其中value = 1
。例如{"gmail_page_viewed" : 1}
如果存在计数器(例如gmail_page_viewed
)键则增加
value = value + 1
如果json计数器存在,请帮我解决插件查询问题。
UPDATE_1(信息:在使用json时始终使用IFNULL)
我使用了@wchiquito建议的解决方案但是看到了以下问题。
第一次(在架构创建之后);试过下面的sql
INSERT INTO `TAG_COUNTER`
(`partner_id`, `time_id`, `counters`)
VALUES
('google', '20180510', '{"gmail_page_viewed": 1}')
ON DUPLICATE KEY UPDATE `counters` =
JSON_SET(`counters`,
'$.gmail_page_viewed',
JSON_EXTRACT(`counters`,
'$.gmail_page_viewed') + 1
);
得到以下回应;这是正确的预期。
'google', '20180510', '{"gmail_page_viewed": 1}'
然后在下一个查询中尝试使用不同的计数器,
INSERT INTO `TAG_COUNTER`
(`account`, `time_id`, `counters`)
VALUES
('google', '20180510', '{"search_page_viewed": 1}')
ON DUPLICATE KEY UPDATE `counters` =
JSON_SET(`counters`,
'$.search_page_viewed',
JSON_EXTRACT(`counters`,
'$.search_page_viewed') + 1
);
并得到了以下内容。
'google', '20180510', '{"gmail_page_viewed": 1, "search_page_viewed": null}'
知道为什么这个新的计数器search_page_viewed设置为NULL ..?
UPDATE_2(INFO:当数字用作键时,在键周围使用双引号)
我也遇到过以下问题,并从那个答案中解决了这个问题
Mysql 5.7 ERROR 3143 (42000): Invalid JSON path expression. The error is around character position 3
UPDATE_3(信息:分组依据,确保WHERE为" NOT NULL"或"> 0"
获取每个时间范围的计数(例如按日,月,年)
SELECT
SUBSTRING(time_id, 1, 6) AS month,
SUM(counters->>'$.gmail_page_viewed')
FROM TAG_COUNTER
WHERE counters->>'$.gmail_page_viewed' > 0
GROUP BY month;
UPDATE_4(问题:)
我希望每次都看到趋势页面(小时/天/月/年) 从下面的查询我可以得到每次的计数,但只有我知道密钥(gmail_page_viewed)。
SELECT
SUBSTRING(time_id, 1, 6) AS month,
SUM(counters->>'$.gmail_page_viewed')
FROM TAG_COUNTER
WHERE counters->>'$.gmail_page_viewed' > 0
GROUP BY month;
但我想知道的是我如何知道每次页数的整体趋势?所以我需要下面的内容,请帮助。
group by SUBSTRING(time_id, 1, 6) AS month, KEY
order by SUM(counters->>'$.KEY')
答案 0 :(得分:2)
以下脚本可满足您的要求:
INSERT INTO `TAG_COUNTER`
(`account`, `time_id`, `counters`)
VALUES
('google', '20180510', '{"gmail_page_viewed": 1, "search_page_viewed": 50}'),
('google', '20180510', '{"gmail_page_viewed": 1, "search_page_viewed": 50}'),
('google', '20180511', '{"gmail_page_viewed": 1, "search_page_viewed": 100}'),
('google', '20180511', '{"gmail_page_viewed": 1, "search_page_viewed": 100}'),
('google', '20180511', '{"gmail_page_viewed": 1, "search_page_viewed": 100}')
ON DUPLICATE KEY UPDATE `counters` =
JSON_SET(`counters`,
'$."gmail_page_viewed"',
IFNULL(`counters` ->> '$."gmail_page_viewed"', 0) + 1,
'$."search_page_viewed"',
IFNULL(`counters` ->> '$."search_page_viewed"', 0) + 1
);
请参阅dbfiddle。