Mysql 如何打印具有特定月份和年份最大销售额的店铺名称?

Mysql 如何打印具有特定月份和年份最大销售额的店铺名称?,mysql,greatest-n-per-group,Mysql,Greatest N Per Group,我的数据库MySQL数据库中有两个表,如下所示: Table No.1 : stores store_id(pk) store_name Table No.2 : sales sale_id(pk) store_id(fk) sale_date sale_amt 在销售表中,同一家商店可以有多个特定月份的销售条目 现在我想打印一个商店的名称,该商店在用户输入的月份和年份中有最多的条目 我应该如何以高效可靠的方式实现这一点?尝试按门店分组,计算每个门店在表A中的交易数量。然后从表A中获取最大交

我的数据库MySQL数据库中有两个表,如下所示:

Table No.1 : stores
store_id(pk)
store_name

Table No.2 : sales
sale_id(pk)
store_id(fk)
sale_date
sale_amt
在销售表中,同一家商店可以有多个特定月份的销售条目

现在我想打印一个商店的名称,该商店在用户输入的月份和年份中有最多的条目


我应该如何以高效可靠的方式实现这一点?

尝试按门店分组,计算每个门店在表A中的交易数量。然后从表A中获取最大交易数量,您将获得一个数字,例如值B。接下来,您可以复制用于获取值B的SQL,并将其放入表a中的Having子句中,类似于:

这是A桌

select count(store_id) as sid
from sales
group by store_id
这是值B

select max(sid)
from( select count(store_id) as sid
    from sales
    group by store_id ) t1
这是具有最大事务数的存储的id

select store_name, count(store_name)
from sales
group by store_name
having count(store_name) =  (select max(sid)
                                from( select count(store_id) as sid
                                        from sales
                                        group by store_id ) t1)
您可以在where子句中添加年和月约束,并将其与stores表连接以获取store\ U名称

select store_name, count(store_name)
from sales, stores
where sales.store_id = stores.store_id
and year(sale_date) = '2015'
and month(sale_date) = '09'
group by store_id, store_name
having count(store_name) =  (select max(sid)
                                from( select count(store_id) as sid
                                        from sales
                                        where year(sale_date) = '2015'
                                        and month(sale_date) = '09'
                                        group by store_id ) t1)
请注意,其他按销售数量重新排列门店并将解决方案限制在第一次注册的解决方案可能是错误的,因为可能有多个门店具有相同的交易数量。此查询将返回具有该销售数量的所有门店

Pd:你可以试试这个解决方案

关于,

在线演示 看我的

结果查询 总清单和一些注释 解释 首先,查询选择每个商店的销售额,这些商店确实通过JOIN销售

第二,我们通过分组统计每家店铺的销售额

在第三步中,我们按照条目数desc对分组结果进行排序,并选择一个具有最高值的via LIMIT

另外,您可以将上述查询与其他答案的查询进行比较,并告诉我们结果:

基准 I'v创造了1000家店铺和1000万销售额。在本地主机Windows NT上测试,5.5.25a-log-MySQL社区服务器GPL,默认my-large.ini配置。表类型为INNODB

使用SQL\u NO\u缓存指令启动3次后的平均exe时间

An3Samiento的解决方案引发语法错误。 1111-组函数的使用无效

zedfoxus的解决方案执行时间为8.8秒 此解决方案的特别说明。如果不同商店的名称相同,则由于group by store_name语句,它们的结果将分组为一个商店的结果

Innos Heo的解决方案引发语法错误 1064-您的SQL语法有错误;检查与您的MySQL服务器版本对应的手册,以了解要使用的正确语法 “销售日期在2015-09-01和2015-09-30之间”附近 按cnt订购 “在8号线

我前面提到的解决方案执行143秒。 但它会区分名称相同但ID不同的商店

尾声 如果您使用大数据,并希望获得最高性能,那么请使用precalc。构造您的数据库级别。第一个将存储所有数据,第二个将回答用户的查询

例如,您可以创建一个表,该表按年份和月份存储每个商店的销售额。要使数据保持最新,可以使用触发器


如果你的数据不是很大,不要参与优化。一切都是针对用例的。

您可以尝试一下:

select store_name
from stores st
inner join sales sa on st.store_id = sa.store_id
where year(sale_date) = <year entered by user>
  and month(sale_date) = <month entered by user>
group by store_name
order by count(*) desc
limit 1;

为了有效地获得它,请在内部联接之前获取top 1 store_id。这会阻止连接一对多关系

SELECT store_name
FROM stores
    INNER JOIN
    (
        SELECT store_id, COUNT(*) AS cnt
        FROM sales
        WHERE sale_date BETWEEN '2015-09-01' AND '2015-09-30'
        GROUP BY store_id
        ORDER BY cnt DESC
        LIMIT 1
    ) max_sales ON stores.store_id = max_sales.store_id;
假设至少存在以下索引:

CREATE INDEX idx1 ON sales (sale_date, store_id);

请尝试此查询。我已经通过创建演示数据库进行了检查

 SELECT COUNT(*) AS total, 
           st.store_name, sl.store_id, sl.sale_date, sl.sale_amt, 
           YEAR(sl.sale_date) as year, 
           MONTH(sl.sale_date) as month 
    FROM stores AS st 
    JOIN sales AS sl ON st.store_id = sl.store_id 
    WHERE YEAR(sl.sale_date)='2015' and MONTH(sl.sale_date)='12' 
    GROUP BY st.store_id
    ORDER BY total
    DESC LIMIT 1
您可以使用此查询

SELECT store_name
FROM stores
WHERE store_id = (
    SELECT store_id
    FROM sales
    WHERE YEAR(sale_date) = '<year value>'
    AND MONTH(sale_date) = '<month value>'
    GROUP BY store_id
    ORDER BY COUNT(*) DESC
    LIMIT 1
)

这将给出所需的结果,并且如果数据库表中的数据较多,它将比连接更快。

这个问题不需要SUMsale\u amt吗


不提供联系

@vkp:在尝试了很多之后,我变得不知所措,因此请求帮助。我添加了一些基准测试感谢您分享测试结果。我的查询有错误。我已经修好了。如果可能的话,你能再测试一次吗?
select store_name
from stores st
inner join sales sa on st.store_id = sa.store_id
where year(sale_date) = <year entered by user>
  and month(sale_date) = <month entered by user>
group by store_name
order by count(*) desc
limit 1;
create index idx_stores_id_name on stores(store_id, store_name);
create index idx_sales_storeid_saledate on sales (store_id, sale_date);
SELECT store_name
FROM stores
    INNER JOIN
    (
        SELECT store_id, COUNT(*) AS cnt
        FROM sales
        WHERE sale_date BETWEEN '2015-09-01' AND '2015-09-30'
        GROUP BY store_id
        ORDER BY cnt DESC
        LIMIT 1
    ) max_sales ON stores.store_id = max_sales.store_id;
CREATE INDEX idx1 ON sales (sale_date, store_id);
 SELECT COUNT(*) AS total, 
           st.store_name, sl.store_id, sl.sale_date, sl.sale_amt, 
           YEAR(sl.sale_date) as year, 
           MONTH(sl.sale_date) as month 
    FROM stores AS st 
    JOIN sales AS sl ON st.store_id = sl.store_id 
    WHERE YEAR(sl.sale_date)='2015' and MONTH(sl.sale_date)='12' 
    GROUP BY st.store_id
    ORDER BY total
    DESC LIMIT 1
SELECT store_name
FROM stores
WHERE store_id = (
    SELECT store_id
    FROM sales
    WHERE YEAR(sale_date) = '<year value>'
    AND MONTH(sale_date) = '<month value>'
    GROUP BY store_id
    ORDER BY COUNT(*) DESC
    LIMIT 1
)
SELECT  
      ( SELECT  store_name
            FROM  Stores
            WHERE  store_id = s.store_id 
      ) AS StoreName
    FROM  Sales s
    WHERE  sale_date >= '2015-09-01'
      AND  sale_date  < '2015-09-01' + INTERVAL 1 MONTH
    GROUP BY  store_id
    ORDER BY  SUM(sale_amt) DESC
    LIMIT  1;