将相似的 meta_key 值分组并使用 meta_value 数据创建结果集
Group similar meta_key values and create result set with meta_value data
我有这样的字段:
meta_key
meta_value
schedule_1_date
2021/2/7
schedule_1_lesson
100
schedule_2_date
2020/12/30
schedule_2_lesson
105
schedule_3_date
2021/2/8
schedule_3_lesson
90
schedule_4_date
2021/5/10
schedule_4_lesson
91
我要select满足条件的数据:
- meta_value schedule_%_date 是 2021/2/7 或 2021/2/8
- schedule_%_lesson 中“%”的数量等于第一个条件中“%”的数量
例如,在上述条件下,我将得到这些数据:
meta_key
meta_value
schedule_1_date
2021/2/7
schedule_1_lesson
100
schedule_3_date
2021/2/8
schedule_3_lesson
90
到目前为止我试过的代码
SELECT * FROM 'table_name' WHERE (meta_key LIKE 'schedule_%_date' AND meta_value IN ('2021/02/07','2021/02/08')) OR (meta_key LIKE 'schedule_%_lesson')
您可以使用 REGEXP
运算符过滤 meta_key
遵循模式 ^schedule_[0-9]+_date$
的行。在派生的 table 中,还会过滤此类行的 meta_value
。使用 replace()
从该行的 meta_key
中删除非数字部分。将派生的 table 加入实际的 table。在 ON
子句中,您可以使用 concat()
和来自派生的 table.[=22= 的 meta_key
的数字部分来构建想要的 meta_key
s ]
SELECT t1.meta_key,
t1.meta_value
FROM elbat t1
INNER JOIN (SELECT replace(replace(meta_key,
'schedule_',
''),
'_date',
'') n
FROM elbat t2
WHERE t2.meta_key REGEXP '^schedule_[0-9]+_date$'
AND t2.meta_value IN ('2021/2/7',
'2021/2/8')) n
ON t1.meta_key IN (concat('schedule_', n.n, '_date'),
concat('schedule_', n.n, '_lesson'));
看看这个:
SELECT tt.meta_key AS lesson_key, tt.meta_value AS lesson_value,
d.meta_key AS date_key, d.meta_value AS date_value
FROM `table_name` tt
JOIN
(SELECT t.*, REPLACE(REPLACE(t.meta_key, 'schedule_', ''), '_date', '') AS key_num
FROM `table_name` t
WHERE t.meta_key LIKE '%schedule%date%'
AND t.meta_value IN ('2021/2/7', '2021/2/8')) d
ON d.key_num = REPLACE(REPLACE(tt.meta_key, 'schedule_', ''), '_lesson', '')
WHERE tt.meta_key LIKE '%schedule%lesson%'
它以稍微不同的格式输出数据,我认为它也可能适用于您:
lesson_key
lesson_value
date_key
date_value
schedule_1_lesson
100
schedule_1_date
2021/2/7
schedule_3_lesson
90
schedule_3_date
2021/2/8
虽然从索引利用率的角度来看,此查询可能不是最佳查询。请务必考虑到这一点。在搜索字符串中间的 LIKE
语句中使用 %
通配符会降低索引的性能。
我假设您对结果集中的 meta_key
没有任何用处,它仅用于分组。
我发现 table 结构对于数据透视查询的设计并不完美,但是通过一些字符串修剪函数,数据透视可以用来简化您的结果集(不需要子查询)。
对 meta_key
列中第二个下划线之前的字符进行分组。然后使用聚合函数在 SELECT.
中隔离所需的值
SELECT
MAX(IF(SUBSTRING_INDEX(meta_key, '_', -1) = 'date', meta_value, NULL)) `date`,
MAX(IF(SUBSTRING_INDEX(meta_key, '_', -1) = 'lesson', meta_value, NULL)) `lesson`
FROM elbat
GROUP BY SUBSTRING_INDEX(meta_key, '_', 2)
HAVING `date` IN ('2021/2/7', '2021/2/8');
date
lesson
2021/2/7
100
2021/2/8
90
我有这样的字段:
meta_key | meta_value |
---|---|
schedule_1_date | 2021/2/7 |
schedule_1_lesson | 100 |
schedule_2_date | 2020/12/30 |
schedule_2_lesson | 105 |
schedule_3_date | 2021/2/8 |
schedule_3_lesson | 90 |
schedule_4_date | 2021/5/10 |
schedule_4_lesson | 91 |
我要select满足条件的数据:
- meta_value schedule_%_date 是 2021/2/7 或 2021/2/8
- schedule_%_lesson 中“%”的数量等于第一个条件中“%”的数量
例如,在上述条件下,我将得到这些数据:
meta_key | meta_value |
---|---|
schedule_1_date | 2021/2/7 |
schedule_1_lesson | 100 |
schedule_3_date | 2021/2/8 |
schedule_3_lesson | 90 |
到目前为止我试过的代码
SELECT * FROM 'table_name' WHERE (meta_key LIKE 'schedule_%_date' AND meta_value IN ('2021/02/07','2021/02/08')) OR (meta_key LIKE 'schedule_%_lesson')
您可以使用 REGEXP
运算符过滤 meta_key
遵循模式 ^schedule_[0-9]+_date$
的行。在派生的 table 中,还会过滤此类行的 meta_value
。使用 replace()
从该行的 meta_key
中删除非数字部分。将派生的 table 加入实际的 table。在 ON
子句中,您可以使用 concat()
和来自派生的 table.[=22= 的 meta_key
的数字部分来构建想要的 meta_key
s ]
SELECT t1.meta_key,
t1.meta_value
FROM elbat t1
INNER JOIN (SELECT replace(replace(meta_key,
'schedule_',
''),
'_date',
'') n
FROM elbat t2
WHERE t2.meta_key REGEXP '^schedule_[0-9]+_date$'
AND t2.meta_value IN ('2021/2/7',
'2021/2/8')) n
ON t1.meta_key IN (concat('schedule_', n.n, '_date'),
concat('schedule_', n.n, '_lesson'));
看看这个:
SELECT tt.meta_key AS lesson_key, tt.meta_value AS lesson_value,
d.meta_key AS date_key, d.meta_value AS date_value
FROM `table_name` tt
JOIN
(SELECT t.*, REPLACE(REPLACE(t.meta_key, 'schedule_', ''), '_date', '') AS key_num
FROM `table_name` t
WHERE t.meta_key LIKE '%schedule%date%'
AND t.meta_value IN ('2021/2/7', '2021/2/8')) d
ON d.key_num = REPLACE(REPLACE(tt.meta_key, 'schedule_', ''), '_lesson', '')
WHERE tt.meta_key LIKE '%schedule%lesson%'
它以稍微不同的格式输出数据,我认为它也可能适用于您:
lesson_key | lesson_value | date_key | date_value |
---|---|---|---|
schedule_1_lesson | 100 | schedule_1_date | 2021/2/7 |
schedule_3_lesson | 90 | schedule_3_date | 2021/2/8 |
虽然从索引利用率的角度来看,此查询可能不是最佳查询。请务必考虑到这一点。在搜索字符串中间的 LIKE
语句中使用 %
通配符会降低索引的性能。
我假设您对结果集中的 meta_key
没有任何用处,它仅用于分组。
我发现 table 结构对于数据透视查询的设计并不完美,但是通过一些字符串修剪函数,数据透视可以用来简化您的结果集(不需要子查询)。
对 meta_key
列中第二个下划线之前的字符进行分组。然后使用聚合函数在 SELECT.
SELECT
MAX(IF(SUBSTRING_INDEX(meta_key, '_', -1) = 'date', meta_value, NULL)) `date`,
MAX(IF(SUBSTRING_INDEX(meta_key, '_', -1) = 'lesson', meta_value, NULL)) `lesson`
FROM elbat
GROUP BY SUBSTRING_INDEX(meta_key, '_', 2)
HAVING `date` IN ('2021/2/7', '2021/2/8');
date | lesson |
---|---|
2021/2/7 | 100 |
2021/2/8 | 90 |