合并 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;