合并 LEFT JOIN 行然后搜索短语
Merge LEFT JOIN rows then search for phrases
我的 mysql 查询有问题。我有两个 tables:
“数据”table:
id
name
1
one
2
two
和“字段”table:
id
data_id
type
value
1
1
1
foostring
2
1
2
barstring
3
1
3
string
4
2
1
foobarstring
5
2
2
string
6
2
3
string
我想获取 ID 与“字段”相关的所有“数据”table 行table,其中“值”列中是短语“foo”和“bar”。两者都用于一个或多个“类型”值。所以我需要合并所有“类型”行中的“值”列,然后搜索短语。我下面的查询在一行中搜索两个短语,然后连接这些行,但我想要相反的结果。先合并再搜索。
SELECT `data`.*, GROUP_CONCAT(`f`.`value`) AS 'value' FROM `data`
LEFT JOIN `fields` AS `f` ON `f`.`data_id` = `data`.`id` AND `f`.`type` IN ('1','2','3')
WHERE `value` LIKE '%foo%' AND `value` LIKE '%bar%'
ORDER BY `name` ASC LIMIT 20;
以上查询 return 只有 1 行 ID 为“2”,因为“fields”中有“foobarstring”table,id 4
id
name
value
2
two
foobarstring
正确的查询应该 return 2 行,因为可以找到 data_id 1 和 2 的两个必需短语。
谢谢
根据您对问题的评论,我认为您想要做的是获取所有数据的列表,其中给定 ID 包含包含“Foo”和“Bar”的任何值,即使它们是单独的记录, 或两个 FooBar 都在一个字符串中。
由于使用了 GROUP_CONCAT(),您需要为每个单独的数据 ID 提供一个“分组依据”子句,否则它会提醒您没有一个,并且您必须包括所有 non-aggregate 组中的列。
至于加入。因为你知道你正在寻找两个可能的字符串,所以我加入字段 table 与别名“f”一样寻找“foo”,但然后再次加入字段 table 别名“ b" 对于“bar”的考虑,还有 f.value < b.value 所以当字符串被 returned 时,它不会 return 一行作为“foo, bar” ,另一个是“bar,foo”,但这个是 LEFT-JOIN,因此不需要辅助连接。
在 WHERE 子句中,我正在测试 f.value 同时具有 foo 和 bar 的条件,如在您的 id = 2 字符串中,或者...第一个包含 foo,第二个别名包含 bar ,因此同一 ID 上的两个不同行。
最后,对于您的专栏,由于可以得到一个 and/or 其他专栏,我已经分别对“foo”和“bar”值进行了 group_concat。
SELECT
d.id,
d.name,
GROUP_CONCAT( f.value ) fValues,
GROUP_CONCAT( b.value ) bValues
FROM
data d
JOIN fields f
ON d.id = f.data_id
AND f.type IN (1, 2, 3)
AND f.value LIKE '%foo%'
LEFT JOIN fields b
ON f.id = b.data_id
AND b.type IN (1, 2, 3)
AND b.value LIKE '%bar%'
AND f.value < b.value
where
( f.value LIKE '%foo%'
AND b.value LIKE '%bar%' )
OR ( b.value IS NULL
AND f.value LIKE '%foo%'
AND f.value LIKE '%bar%' )
group by
d.id,
d.name
ORDER BY
d.name
LIMIT
20;
最终结果是这样的,效果非常好:
SELECT data.*, f.val FROM data
LEFT JOIN (
SELECT data_id, GROUP_CONCAT(value) val
FROM fields WHERE type IN ('1','2','3')
GROUP BY data_id
) f ON f.data_id = data.id
WHERE val LIKE '%foo%' AND val LIKE '%bar%'
ORDER BY name ASC LIMIT 20;
我的 mysql 查询有问题。我有两个 tables:
“数据”table:
id | name |
---|---|
1 | one |
2 | two |
和“字段”table:
id | data_id | type | value |
---|---|---|---|
1 | 1 | 1 | foostring |
2 | 1 | 2 | barstring |
3 | 1 | 3 | string |
4 | 2 | 1 | foobarstring |
5 | 2 | 2 | string |
6 | 2 | 3 | string |
我想获取 ID 与“字段”相关的所有“数据”table 行table,其中“值”列中是短语“foo”和“bar”。两者都用于一个或多个“类型”值。所以我需要合并所有“类型”行中的“值”列,然后搜索短语。我下面的查询在一行中搜索两个短语,然后连接这些行,但我想要相反的结果。先合并再搜索。
SELECT `data`.*, GROUP_CONCAT(`f`.`value`) AS 'value' FROM `data`
LEFT JOIN `fields` AS `f` ON `f`.`data_id` = `data`.`id` AND `f`.`type` IN ('1','2','3')
WHERE `value` LIKE '%foo%' AND `value` LIKE '%bar%'
ORDER BY `name` ASC LIMIT 20;
以上查询 return 只有 1 行 ID 为“2”,因为“fields”中有“foobarstring”table,id 4
id | name | value |
---|---|---|
2 | two | foobarstring |
正确的查询应该 return 2 行,因为可以找到 data_id 1 和 2 的两个必需短语。
谢谢
根据您对问题的评论,我认为您想要做的是获取所有数据的列表,其中给定 ID 包含包含“Foo”和“Bar”的任何值,即使它们是单独的记录, 或两个 FooBar 都在一个字符串中。
由于使用了 GROUP_CONCAT(),您需要为每个单独的数据 ID 提供一个“分组依据”子句,否则它会提醒您没有一个,并且您必须包括所有 non-aggregate 组中的列。
至于加入。因为你知道你正在寻找两个可能的字符串,所以我加入字段 table 与别名“f”一样寻找“foo”,但然后再次加入字段 table 别名“ b" 对于“bar”的考虑,还有 f.value < b.value 所以当字符串被 returned 时,它不会 return 一行作为“foo, bar” ,另一个是“bar,foo”,但这个是 LEFT-JOIN,因此不需要辅助连接。
在 WHERE 子句中,我正在测试 f.value 同时具有 foo 和 bar 的条件,如在您的 id = 2 字符串中,或者...第一个包含 foo,第二个别名包含 bar ,因此同一 ID 上的两个不同行。
最后,对于您的专栏,由于可以得到一个 and/or 其他专栏,我已经分别对“foo”和“bar”值进行了 group_concat。
SELECT
d.id,
d.name,
GROUP_CONCAT( f.value ) fValues,
GROUP_CONCAT( b.value ) bValues
FROM
data d
JOIN fields f
ON d.id = f.data_id
AND f.type IN (1, 2, 3)
AND f.value LIKE '%foo%'
LEFT JOIN fields b
ON f.id = b.data_id
AND b.type IN (1, 2, 3)
AND b.value LIKE '%bar%'
AND f.value < b.value
where
( f.value LIKE '%foo%'
AND b.value LIKE '%bar%' )
OR ( b.value IS NULL
AND f.value LIKE '%foo%'
AND f.value LIKE '%bar%' )
group by
d.id,
d.name
ORDER BY
d.name
LIMIT
20;
最终结果是这样的,效果非常好:
SELECT data.*, f.val FROM data
LEFT JOIN (
SELECT data_id, GROUP_CONCAT(value) val
FROM fields WHERE type IN ('1','2','3')
GROUP BY data_id
) f ON f.data_id = data.id
WHERE val LIKE '%foo%' AND val LIKE '%bar%'
ORDER BY name ASC LIMIT 20;