Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 选择分组子句中计数的最大值_Mysql_Subquery_Mysql 5.7 - Fatal编程技术网

Mysql 选择分组子句中计数的最大值

Mysql 选择分组子句中计数的最大值,mysql,subquery,mysql-5.7,Mysql,Subquery,Mysql 5.7,我有以下表格: Vehicles(v͟i͟n͟, model,category) Sales(s͟a͟l͟e͟I͟D͟, staffID,customerID,date) vehicleSold(saleID,v͟i͟n͟,salePrice) 当我使用以下方法连接这些表时: select YEAR(Sales.saleDate) , Vehicles.model , count(Vehicles.model) 'Sold' , Vehicles.category

我有以下表格:

Vehicles(v͟i͟n͟, model,category)
Sales(s͟a͟l͟e͟I͟D͟, staffID,customerID,date)
vehicleSold(saleID,v͟i͟n͟,salePrice)
当我使用以下方法连接这些表时:

select YEAR(Sales.saleDate)
     , Vehicles.model
     , count(Vehicles.model) 'Sold'
     , Vehicles.category
  from Vehicles 
  JOIN vehicleSold
    on Vehicles.vin = vehicleSold.vin
  JOIN Sales 
    on Sales.saleID = vehicleSold.saleID
 group 
    by YEAR(Sales.saleDate)
     , Vehicles.model
     , Vehicles.category;
结果是:

+----------------------+-------------+------+----------------+
| YEAR(Sales.saleDate) | model       | Sold | category       |
+----------------------+-------------+------+----------------+
|                 2020 | Altima      |    1 | car            |
|                 2020 | Flying Spur |    2 | car            |
|                 2020 | Lifan E3    |    3 | Electric Moped |
|                 2020 | Ridgeline   |    2 | truck          |
|                 2020 | Shiver      |    4 | motorbike      |
+----------------------+-------------+------+----------------+

从这张表中,我想得到一个类别中最畅销的型号。所以,在这种情况下,我只想返回2020年,飞马,汽车作为唯一的一排类别的汽车,因为它是最畅销的2020年在其类别。我尝试使用子查询is MAX(COUNT(*),但我猜mysql中不支持这种情况。如果有人能指出我的错误,并知道如何做到这一点,那将是巨大的帮助

假设您使用支持
row\u number()
rank()
的MySQL版本8或更高版本,您可以使用这些窗口函数之一

如果每个类别只能有一行,请使用
row_number()
,或者如果您想包括排名靠前的任何型号,请像这样使用
rank()

select Yr
     , model
     , Sold
     , ctegory
from (
    select YEAR(Sales.saleDate) Yr
         , Vehicles.model
         , count(Vehicles.model) 'Sold'
         , Vehicles.category
         , ROW_NUMBER() OVER(PARTITION BY YEAR(Sales.saleDate), category 
                             ORDER BY sold DESC)
           as rn
      from Vehicles 
      JOIN vehicleSold
        on Vehicles.vin = vehicleSold.vin
      JOIN Sales 
        on Sales.saleID = vehicleSold.saleID
     group 
        by YEAR(Sales.saleDate)
         , Vehicles.model
         , Vehicles.category
    ) as d
where rn = 1
对于rank,语法几乎相同:

     , RANK() OVER(PARTITION BY YEAR(Sales.saleDate), category 
                   ORDER BY sold DESC)
       as rnk
注:

  • 与group by一起使用时,这些窗口功能在group by执行后执行
  • 如果您没有MySQL 8或更高版本,请记住在问题中告诉我们您的db版本,以便建议的解决方案对您更有用

  • dbfiddle

    对于8之前的MySQL版本(其中
    row_number()
    不可用),有一种方法模仿
    row_number()
    ,这在实践中是可行的,但被一些人认为是“黑客”

    它的工作原理是使用一个子查询,必须使用一个
    order by
    子句,这种排序将允许我们确定何时为数据的每个“分组”分配1。这里我将“组”的年份和类别连接起来,如果连接与前一行相同,则行号递增,如果连接与前一行不同,则行号为1。此逻辑由下面所示的
    IF()
    函数执行

    SELECT
          yr
        , model
        , sold
        , category
    FROM (
        SELECT
              @row_num :=IF(@prev_value=concat(yr, category),@row_num + 1, 1) AS rn
            , yr
            , model
            , sold
            , category
            , @prev_value := concat(yr, category)
        FROM mytable
        CROSS JOIN (SELECT @row_num :=1,  @prev_value :='') vars
        ORDER BY
                yr
              , category
              , sold DESC
        ) as d
    WHERE rn = 1
    
    再加上一点技巧,我们可以将行数模拟扩展到排名模拟,以便返回最高位置的平局:

    SELECT
          yr
        , model
        , sold
        , category
    FROM (
        SELECT
              @row_num :=IF(@prev_value=concat(yr, category)
                            , IF(@sold = sold, @row_num, @row_num + 1)
                        , 1) AS rnk
            , yr
            , model
            , sold
            , category
            , @prev_value := concat(yr, category)
            , @sold := sold
        FROM mytable
        CROSS JOIN (SELECT @row_num :=1,  @prev_value :='', @sold := 1) vars
        ORDER BY
                yr
              , category
              , sold DESC
        ) as d
    WHERE rnk = 1
    

    dbfiddle

    查看MySQL的哪个版本?版本8或更高版本的功能可以轻松解决此问题,以前的版本需要不同的方法。请始终指定您的dbms版本。如果Altima在2020年也销售了2,会发生什么情况?i、 e.如果一年内销售最多的一行超过一行,会发生什么?很抱歉,我不使用版本8,我使用旧版本进行学习。版本5.7。如果你让我知道如何在这个版本,这将是伟大的!