如何在选择语句中根据条件选择最大值?

huangapple go评论141阅读模式
英文:

How to select maximum values on condition from select statement?

问题

我有以下具有多个条目的表格:

国家 日期 制造商
英国 01-01-2020 大众
英国 01-01-2020 大众
英国 01-02-2020 大众
丹麦 13-01-2020 奥迪
........ ....... .......

每一行代表一辆汽车的销售,来自一个国家,有一个特定的日期以及售出的汽车制造商。我有来自两个月份(2020年1月和2月)的数据,涵盖两个国家,英国和丹麦。在这些月份中,多个汽车制造商销售了汽车(不仅仅是表格中显示的大众和奥迪)。我想要获取每个国家和每个月份的某个制造商的最畅销汽车以及该特定制造商的汽车销售数量。

我尝试了这段代码:

SELECT
    Country,
    DATENAME(MONTH, Date) AS Month,
    Manufacturer,
    COUNT(*) AS no_of_sales 
FROM
    table
GROUP BY
    Country,
    DATENAME(MONTH, Date),
    Manufacturer
ORDER BY
    no_of_sales DESC

但是这样做会为每个国家、每个月份和每个制造商获取他们销售了多少辆汽车。在这种情况下,我只想获取4行:

国家 日期 制造商 no_of_sales
英国 一月 大众 13
英国 二月 保时捷 15
丹麦 一月 大众 10
丹麦 二月 奥迪 12

基本上,我不确定如何过滤上面我写的SELECT语句。希望我表达清楚,让您能够理解。

英文:

I have the following table with multiple entries:

Country Date Manufacturer
UK 01-01-2020 VW
UK 01-01-2020 VW
UK 01-02-2020 VW
Denmark 13-01-2020 Audi
........ ....... .......

Each line represents the sale of a car, from a country, from a specific date and the manufacturer of the car sold. I have data from two months (January and February of 2020), for two countries, UK and Denmark. In these months multiple car manufacturers have sold cars (not only VW and Audi as the table shows). I want to obtain for each country and each month the most sold cars for a certain manufacturer and the number of cars sold for that specific manufacturer.

I tried this code:

SELECT
    Country,
    DATENAME(MONTH, Date) AS Month,
    Manufacturer,
    COUNT(*) AS no_of_sales 
FROM
    table
GROUP BY
    Country,
    DATENAME(MONTH, Date),
    Manufacturer
ORDER BY
    no_of_sales DESC

But this way I obtain for each country, each month and for each manufacturer how many cars they sold. I want to obtain only 4 rows in this case:

Country Date Manufacturer no_of_sales
UK January VW 13
UK February Porsche 15
Denmark January VW 10
Denmark Februray Audi 12

Basically I am not sure how to filter the select statement that I wrote above. Hope I was clear enough for you to understand.

答案1

得分: 0

方法1:我知道我想要查看哪两个制造商。这可以通过简单的WHERE子句来完成。

SELECT
        S.Country
       ,DATENAME( MONTH, S.Sale_Date ) AS 'Month'
       ,S.Manufacturer
       ,COUNT(*)                       AS 'NbrOfSales'
   FROM
         #SALES  S
  WHERE
         S.Manufacturer IN ( 'VW', 'Audi' )
GROUP BY 
          S.Country
         ,DATENAME( MONTH, S.Sale_Date )
         ,S.Manufacturer
ORDER BY
          NbrOfSales  DESC
;

产生的结果为:

+---------+---------+--------------+------------+
| Country |  Month  | Manufacturer | NbrOfSales |
+---------+---------+--------------+------------+
| UK      | January | VW           |          3 |
| Denmark | January | Audi         |          1 |
+---------+---------+--------------+------------+

**方法2:**我不知道我想要哪些制造商。我只想要那个月销量最高的制造商。这种方法要求首先对销售进行分组,然后对行进行编号。您可以在通用表达式(CTE)中执行此操作,然后选择每个组的第一行。ROW_NUMBER()函数按国家和月份名称分区,以使每个制造商获得唯一的行号。分区按销售计数降序排序,以便第一个行号始终具有在分区中销售最多的制造商。

WITH SALES_COUNT AS (
     SELECT
             S.Country
            ,DATENAME( MONTH, S.Sale_Date ) AS 'Month'
            ,S.Manufacturer
            ,COUNT(*)                       AS 'NbrOfSales'
            ,ROW_NUMBER() OVER (PARTITION BY
                                              S.Country
                                             ,DATENAME( MONTH, S.Sale_Date )
                                ORDER BY
                                              COUNT(*)  DESC) AS 'ROW_NBR'
       FROM
             #SALES  S
    GROUP BY 
              S.Country
             ,DATENAME( MONTH, S.Sale_Date )
             ,S.Manufacturer
)
SELECT
        *
  FROM
        SALES_COUNT  SC
 WHERE
        SC.ROW_NBR = 1
;

产生的结果为:

+---------+---------+--------------+------------+---------+
| Country |  Month  | Manufacturer | NbrOfSales | ROW_NBR |
+---------+---------+--------------+------------+---------+
| Denmark | January | Audi         |          1 |       1 |
| UK      | January | VW           |          3 |       1 |
+---------+---------+--------------+------------+---------+

也许还有其他方法来看待您的问题,但这是我能想到的两种方法。

英文:

The way I read your question is that you are able to count the sales of cars by manufacturer, month, and country. That gives you what you want, but you're only interested in the results from a specific set of manufacturers. I interpret this two ways.

My example uses the following data:

SELECT
        Country
       ,Sale_Date
       ,Manufacturer
  INTO
        #SALES
  FROM  (
           VALUES
           ( 'UK', CAST( '20200101' AS date ), 'VW' )
          ,( 'UK', CAST( '20200101' AS date ), 'VW' )
          ,( 'UK', CAST( '20200102' AS date ), 'VW' )
          ,( 'UK', CAST( '20200103' AS date ), 'Porsche' )
          ,( 'Denmark', CAST( '20200113' AS date ), 'Audi' )
        ) S(Country, Sale_Date, Manufacturer)
;

Method 1: I know which two manufacturers I want to see. This is done by a simple WHERE clause.

 SELECT
         S.Country
        ,DATENAME( MONTH, S.Sale_Date ) AS 'Month'
        ,S.Manufacturer
        ,COUNT(*)                       AS 'NbrOfSales'
   FROM
         #SALES  S
  WHERE
         S.Manufacturer IN ( 'VW', 'Audi' )
GROUP BY 
          S.Country
         ,DATENAME( MONTH, S.Sale_Date )
         ,S.Manufacturer
ORDER BY
          NbrOfSales  DESC
;

Which produces:

+---------+---------+--------------+------------+
| Country |  Month  | Manufacturer | NbrOfSales |
+---------+---------+--------------+------------+
| UK      | January | VW           |          3 |
| Denmark | January | Audi         |          1 |
+---------+---------+--------------+------------+

Method 2: I don't know which manufacturers I want. I only want the one that sold the most cars that month. This method requires that you first group your sales and then number the rows. You can do this in a Common Table Expression (CTE) and then select the first row of each group. The ROW_NUMBER() function is partitioned by country and month name so each manufacturer gets a unique row number. The partitions are ordered descending by sales count so that row number one always has the manufacturer who had the most sales in the partition.

WITH SALES_COUNT AS (
     SELECT
             S.Country
            ,DATENAME( MONTH, S.Sale_Date ) AS 'Month'
            ,S.Manufacturer
            ,COUNT(*)                       AS 'NbrOfSales'
            ,ROW_NUMBER() OVER (PARTITION BY
                                              S.Country
                                             ,DATENAME( MONTH, S.Sale_Date )
                                ORDER BY
                                              COUNT(*)  DESC) AS 'ROW_NBR'
       FROM
             #SALES  S
    GROUP BY 
              S.Country
             ,DATENAME( MONTH, S.Sale_Date )
             ,S.Manufacturer
)
SELECT
        *
  FROM
        SALES_COUNT  SC
 WHERE
        SC.ROW_NBR = 1
;

Which produces:

+---------+---------+--------------+------------+---------+
| Country |  Month  | Manufacturer | NbrOfSales | ROW_NBR |
+---------+---------+--------------+------------+---------+
| Denmark | January | Audi         |          1 |       1 |
| UK      | January | VW           |          3 |       1 |
+---------+---------+--------------+------------+---------+

There may be other ways of looking at your question, but those are the only two that jump out to me.

huangapple
  • 本文由 发表于 2023年8月10日 21:13:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76876063.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定