【问题标题】:MySQL count results in a subquery with unionMySQL 计数导致带有联合的子查询
【发布时间】:2017-04-22 23:46:51
【问题描述】:

我有一些关于 UNION 的查询,我想计算它们并在另一个查询中显示为一行

示例:我有一张名为“clients”的表,他们可以在 store1、store2 或 store 3 上购买,我需要在名为“sales”的一行中显示他们的姓名和购买的商品数量

SELECT name,COUNT(*) FROM(
    SELECT 1 FROM store1 WHERE store1.client=clients.id
    UNION
    SELECT 1 FROM store2 WHERE store2.client=clients.id
    UNION
    SELECT 1 FROM store3 WHERE store3.client=clients.id
) sales
FROM clients

如果 john 从 store 2 购买了 2 件商品,从 store 3 购买了 1 件商品,而 mary 没有购买任何东西,那么预期的结果是这样的:

name | sales
------------
john | 3
mary | 0

但我遇到的是这个错误:

您的 SQL 语法有错误;查看与您的 MySQL 服务器版本相对应的手册,了解在“FROM 客户端”附近使用的正确语法

这是使用另一个选择子查询的另一种尝试:

SELECT name,(
    SELECT COUNT(*) FROM(
        SELECT 1 FROM store1 WHERE store1.client=clients.id
        UNION
        SELECT 1 FROM store2 WHERE store2.client=clients.id
        UNION
        SELECT 1 FROM store3 WHERE store3.client=clients.id
    ) xxxx -- (mandatory table name)
) sales
FROM clients

这给了我这个错误:

“where 子句”中的未知列“clients.id”

希望你能帮助我,提前谢谢你!

【问题讨论】:

    标签: mysql union


    【解决方案1】:

    首先合并表,然后过滤结果和计数...

    您不能引用超过 1 级分隔的字段。由于 store1.client 的深度为 2 级,且 clients 为 0 级,因此您的分离级别超过 1 级,这是不允许的。

       SELECT C.name, count(1)
       FROM (
            SELECT 'Store1' as StoreTable, a.* FROM store1 a UNION
            SELECT 'Store2', b.* FROM store2 b UNION
            SELECT 'Store3', c.* FROM store3 c
        ) S
        RIGHT JOIN clients C
         on C.ID = S.Client       
        GROUP BY Name
    

    这做了一些假设

    1. 每个存储表之间的数据结构都是一样的
    2. 您可能需要现在可以访问的 stores 表中的其他数据。

    我可能会更进一步,只需创建一个名为“Stores”的视图,将所有“Stores”连接到一个联合中,以简化跨商店的其他查询。并通过硬编码视图中的“StoreTable 名称”,您始终可以在需要时识别源表。

    【讨论】:

    • 如果您想要计数为 0 的客户,您需要在我的示例中使内部连接正确。
    • 您是对的,您可以编辑查询以获取 RIGHT JOIN 以将其标记为解决方案吗?
    【解决方案2】:

    差不多了。尝试类似:

    SELECT c.name, sum(s.qt) as qt
    from clients c
    join (
        SELECT client.id, COUNT(*) FROM(
            SELECT client, sum(1) as qt FROM store1 group by client
            UNION
            SELECT client, sum(1) as qt FROM store2 group by client
            UNION
            SELECT client, sum(1) as qt FROM store3 group by client
        ) as sales s on (s.client = c.id)
    group by c.name
    

    我可能会对 MySQL 和 SQLServer 感到困惑,我会进行测试并让您知道是否有不同之处。

    更新:更正了子查询,添加了 sum 和 group_by 并删除了 where 子句。如果您不想从所有商店获得所有客户,它可能会对性能产生影响。

    【讨论】:

    • 子查询中不需要GROUP BY 吗?而s.client_id 应该是s.id
    • 可能是的。我使用了发布的原始结构。可能 sum(qt) 并按 client_id 分组。关于你是对的 id。
    【解决方案3】:
     SELECT name,COUNT(*)  
     FROM clients  INNER JOIN
         (
         SELECT client as id, 1 FROM store1 
             UNION
         SELECT client as id, 1 FROM store2 
             UNION
         SELECT client as id, 1 FROM store3
         )
    
         as Stores on clients.id = Stores.id
         GROUP by name
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-03
      • 2023-01-31
      • 1970-01-01
      • 1970-01-01
      • 2015-02-22
      相关资源
      最近更新 更多