【问题标题】:Mysql, how to select based on result set from another query in one shotMysql,如何一次根据另一个查询的结果集进行选择
【发布时间】:2018-03-08 19:04:31
【问题描述】:

我有两张表,我们先叫它brand_table,结构如下:

<table>
  <tr>
    <th>brand_id</th>
    <th>brand_name</th>
  </tr>
  <tr>
    <td>1</td>
    <td>Honda</td>
  </tr>
  <tr>
    <td>2</td>
    <td>Ford</td>
  </tr>
</table>

另一个是user_table,结构如下:

<table>
  <tr>
    <th>user_id</th>
    <th>username</th>
    <th>favorite_brands</th>
  </tr>
  <tr>
    <td>1</td>
    <td>John Wick</td>
    <td>1,2</td>
  </tr>
  <tr>
    <td>2</td>
    <td>Jack Reaper</td>
    <td>2</td>
  </tr>
  <tr>
    <td>2</td>
    <td>Han Solo</td>
    <td>1</td>
  </tr>
</table>

大概,我可以通过以下方式知道有多少用户喜欢某个特定品牌:

select  count(*)
    from  table_user
    where  favorite_brands like 
    (
        SELECT  concat('%', brand_id, '%')
            from  brand_table
            where  brand_id = <brand_id>
    ) 

现在,如果我想知道喜欢每个品牌的用户总数,那么我必须分两个阶段进行,甚至在编程方面进行:

  • 首先,加载所有品牌并将它们存储在结果集中
  • 其次,遍历结果集,找出每个brand_id的总用户数

我想做的是在单个查询中执行此操作。

谁能帮帮我?

【问题讨论】:

  • 为什么该表有一条user_id 1 记录,favourite_brands1,2 而不是user_id 1 的两条记录,每个用户喜欢的品牌都有一条记录?
  • 提示:使用FIND_IN_SET() 而不是LIKE
  • 既然你有&lt;brand_id&gt;,就不要使用SELECT!无论如何,当你最终得到"3,12" LIKE '%1%' 时会发生什么——错误的结果。
  • 感谢@RickJames,非常周到

标签: mysql sql optimization mariadb


【解决方案1】:

根据给定用户的品牌列表中出现的给定品牌加入两个表。为此,我们可以使用FIND_IN_SET,它可以搜索给定输入的 CSV 值列表。作为FIND_IN_SET 工作原理的示例,FIND_IN_SET('1', '1,2,3') 将返回索引 1,因为1 作为 CSV 列表中的第一个值出现。 FIND_IN_SET 不匹配返回零,因此只要返回非零值,我们就可以假设 CSV 包含我们感兴趣的值。

SELECT
    t1.brand_id,
    t1.brand_name,
    COUNT(t2.favorite_brands) AS cnt
FROM brand_table t1
LEFT JOIN user_table t2
    ON FIND_IN_SET(t1.brand_id, t2.favorite_brands) > 0
GROUP BY
    t1.brand_id,
    t1.brand_name

输出:

    brand_id    brand_name  cnt
1   1           Honda       2
2   2           Ford        2

演示在这里:

Rextester

【讨论】:

  • 不错的答案蒂姆·比格莱森
【解决方案2】:

使用这个查询

select count(*) from user_table where FIND_IN_SET(<brand_id>,favorite_brands); 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 2018-09-01
    相关资源
    最近更新 更多