Transact-SQL - 带有额外组的最大计数

时间:2016-06-20 09:50:43

标签: sql tsql

昨天我在SQL脚本上苦苦挣扎。我仍然没有得到理想的解决方案。我将此SQL脚本用于我的SSIS项目(datawarehousing)中的报告。

我有几个连接的查询。我使用的表格如下:

Factales - 单个客户的单个客户的单个客户的单个车辆的大量汇总(参考)钥匙和销售价格的事实表

DimDate - 2001年至2007年间具有不同日期符号的表格

dimcar - 有关汽车,购物车类型和制造商名称的信息

我想创建一个脚本来显示每年(每年)销售的最大车辆

我的查询是这样的

SELECT Count(*) most_cars_sold, 
       Car.carmodeltype, 
       Car.carmodeldetails, 
       Car.manufacturername, 
       dd.year 
FROM   factsales sale 
       INNER JOIN dimdate dd 
               ON dd.date_sid = sale.orderdate_sid 
       LEFT JOIN dimcar car 
              ON car.car_sid = sale.car_sid 
GROUP  BY Car.carmodeltype, 
          Car.carmodeldetails, 
          Car.manufacturername, 
          dd.year 

结果是:

6   406     Break HDI 110pk XT  Peugeot 2000
4   Civic   DX 2dr  Honda   2000
4   Octavia Combi TDi 74kW Comf4x4  Skoda   2000
3   Megane  1.5dCi Expressi.Basi.5d Renault 2000
3   Polo    1.9TDI Sportline 5drs   Volkswagen  2000
3   Touran  2.0TDI Trendline    Volkswagen  2000
3   Vectra  2.0DTi Comfort 4drs Opel    2000
3   Corolla D4-D 116 Sol Bus.   Toyota  2000
3   Corolla Verso 2.0D4-D 90 Terra  Toyota  2000
3   406     Break HDI 110pk GT  Peugeot 2000

此示例仅显示2000,但结果将显示为2007年

然而..我只想显示 " 6 406打破HDI 110pk XT Peugeot 2000"

然后我尝试了这个查询:

SELECT Max(most_cars_sold) maxSold, 
       year 
FROM   (SELECT Count(*) most_cars_sold, 
               Car.carmodeltype, 
               Car.carmodeldetails, 
               Car.manufacturername, 
               dd.year 
        FROM   factsales sale 
               INNER JOIN dimdate dd 
                       ON dd.date_sid = sale.orderdate_sid 
               LEFT JOIN dimcar car 
                      ON car.car_sid = sale.car_sid 
        GROUP  BY Car.carmodeltype, 
                  Car.carmodeldetails, 
                  Car.manufacturername, 
                  dd.year) foo 
GROUP  BY year 
ORDER  BY year, 
          maxsold DESC 

结果:

6   2000
6   2001
4   2002
5   2003
4   2004
4   2005
5   2006
2   2007

看起来很好..但我在结果中也需要CarModelType, CarModelDetails, ManufacturerName ..

有人可以帮忙吗?

4 个答案:

答案 0 :(得分:0)

试试这个,如果您使用PostgreSQL或Oracle,您可以使用Windows函数更短的脚本

SELECT a.maxSold,
       a.year,
       b.carmodeltype,
       b.carmodeldetails,
       b.manufacturername
FROM (
SELECT Max(most_cars_sold) maxSold, 
       year 
FROM   (SELECT Count(*) most_cars_sold, 
               Car.carmodeltype, 
               Car.carmodeldetails, 
               Car.manufacturername, 
               dd.year 
        FROM   factsales sale 
               INNER JOIN dimdate dd 
                       ON dd.date_sid = sale.orderdate_sid 
               LEFT JOIN dimcar car 
                      ON car.car_sid = sale.car_sid 
        GROUP  BY Car.carmodeltype, 
                  Car.carmodeldetails, 
                  Car.manufacturername, 
                  dd.year) foo 
GROUP  BY year 
ORDER  BY year, 
          maxsold DESC )a
INNER JOIN (SELECT Count(*) most_cars_sold, 
               Car.carmodeltype, 
               Car.carmodeldetails, 
               Car.manufacturername, 
               dd.year 
        FROM   factsales sale 
               INNER JOIN dimdate dd 
                       ON dd.date_sid = sale.orderdate_sid 
               LEFT JOIN dimcar car 
                      ON car.car_sid = sale.car_sid 
        GROUP  BY Car.carmodeltype, 
                  Car.carmodeldetails, 
                  Car.manufacturername, 
                  dd.year) b on b.most_cars_sold=a.maxSold

答案 1 :(得分:0)

WITH TIES当您想要返回两个或多个在有限结果集中最后一个位置的行时使用。必须与ORDER BY子句一起使用。 WITH TIES可能会导致返回的行数多于表达式中指定的值。例如,如果expression设置为5但是另外两行与第5行中ORDER BY列的值匹配,则结果集将包含7行

----------------------------------------------------------------------------
--Test tables start
----------------------------------------------------------------------------
if object_id(N'tempdb..#factsales', N'U') is not null drop table #factsales;
select [orderdate_sid] = 1, [car_sid] = 1
into #factsales
union all select 1, 1
union all select 1, 2
union all select 1, 2
union all select 1, 3
union all select 2, 1
union all select 2, 3
union all select 3, 1
union all select 3, 2
union all select 3, 2;
--select * from #factsales

if object_id(N'tempdb..#dimdate', N'U') is not null drop table #dimdate;
select [date_sid] = 1, [year] = 2000
into #dimdate
union all select 2, 2002
union all select 3, 2003;
--select * from #dimdate

if object_id(N'tempdb..#dimcar', N'U') is not null drop table #dimcar;
select [car_sid] = 1, [carmodeltype] = N'406', [carmodeldetails] = N'Break HDI 110pk XT', [manufacturername] = N'Peugeot'
into #dimcar
union all select 2, N'Civic', N'DX 2dr', N'Peugeot'
union all select 3, N'Octavia', N'Combi TDi 74kW Comf4x4', N'Skoda';
--select * from #dimcar
----------------------------------------------------------------------------
--Test tables end
---------------------------------------------------------------------------- 

select top(1) with ties
        sq.*
from
(
    select [most_cars_sold] = count(*)
           ,car.[carmodeltype]
           ,car.[carmodeldetails]
           ,car.[manufacturername]
           ,dd.[year]
    from #factsales as sale 
    join #dimdate as dd on dd.[date_sid] = sale.[orderdate_sid]
    left join #dimcar as car on car.[car_sid] = sale.[car_sid]
    group  by car.[carmodeltype], car.[carmodeldetails], car.[manufacturername], dd.[year]
) as sq
order by dense_rank() over(partition by sq.[year] order by [most_cars_sold] desc);

答案 2 :(得分:0)

SELECT Max(most_cars_sold) OVER (PARTITION BY Year) maxSold
    ,Year
    ,carmodeltype
    ,carmodeldetails
    ,manufacturername
FROM (
    SELECT Count(*) most_cars_sold
        ,Car.carmodeltype
        ,Car.carmodeldetails
        ,Car.manufacturername
        ,dd.year
    FROM factsales sale
    INNER JOIN dimdate dd ON dd.date_sid = sale.orderdate_sid
    LEFT JOIN dimcar car ON car.car_sid = sale.car_sid
    GROUP BY Car.carmodeltype
        ,Car.carmodeldetails
        ,Car.manufacturername
        ,dd.year
    ) foo
ORDER BY YEAR

答案 3 :(得分:0)

我找到了自己的解决方案..如果你问我,这是一种非常特殊的方法......但结果很有希望

SELECT Concat(Cast(Max(most_cars_sold) AS NVARCHAR(255)), year), 
       Max(most_cars_sold) cars_sold, 
       year, 
       carmodeltype, 
       carmodeldetails, 
       manufacturername 
FROM   (SELECT Count(*) most_cars_sold, 
               Car.carmodeltype, 
               Car.carmodeldetails, 
               Car.manufacturername, 
               dd.year 
        FROM   factsales sale 
               INNER JOIN dimdate dd 
                       ON dd.date_sid = sale.orderdate_sid 
               LEFT JOIN dimcar car 
                      ON car.car_sid = sale.car_sid 
        GROUP  BY Car.carmodeltype, 
                  Car.carmodeldetails, 
                  Car.manufacturername, 
                  dd.year) foo 
GROUP  BY year, 
          carmodeltype, 
          carmodeldetails, 
          manufacturername 
HAVING Concat(Cast(Max(most_cars_sold) AS NVARCHAR(255)), year) IN (SELECT 
       Concat(Cast(Max(most_cars_sold) AS NVARCHAR(255)), year) 
                                                                    FROM   ( 
       SELECT 
              Count(*) most_cars_sold, 
              Car.carmodeltype, 
              Car.carmodeldetails, 
              Car.manufacturername, 
              dd.year 
                                                                            FROM 
              factsales sale 
              INNER JOIN dimdate dd 
                      ON dd.date_sid = sale.orderdate_sid 
              LEFT JOIN dimcar car 
                     ON car.car_sid = sale.car_sid 
              GROUP  BY Car.carmodeltype, 
                        Car.carmodeldetails, 
                        Car.manufacturername, 
                        dd.year) foo 
       GROUP  BY year) 
ORDER  BY year 

我做了什么:)我已经将cars_sold与年份联系起来,以作出独特的参考 稍后我会在having子句上使用相同的查询来比较唯一性和仅基于most_cars_sold和year的查询..

我喜欢它:D

结果是

62000   6   2000    406     Break HDI 110pk XT  Peugeot
62001   6   2001    406     Break HDI 110pk XT  Peugeot
42002   4   2002    Astra   2.2DTi Njoy 5drs    Opel 
42002   4   2002    Vectra  GTS 2.2DTi Elegance Opel 
52003   5   2003    Laguna  Gr.Tour dCi 100pk Auth. Renault
42004   4   2004    406     Break HDI 90pk XT   Peugeot
42004   4   2004    Zafira  2.2DTi Elegance     Opel 
42004   4   2004    Passat  1.9TDI 74kW Comfortline Volkswagen
42005   4   2005    Passat  Var.TDI 96kW H5 Comfl.  Volkswagen
42005   4   2005    Polo    1.4TDI Atlantic 5drs    Volkswagen
42005   4   2005    Megane  1.9dCi Privileg.Comf.5d Renault
52006   5   2006    406     Break HDI 90pk XT   Peugeot
22007   2   2007    A   160CDI Elegance     Mercedes-Benz
22007   2   2007    Golf    1.9TDI 74kW Basis Tip.3dr   Volkswagen
22007   2   2007    Ibiza   1.9TDi 96kW Sport 3drs  Seat 
相关问题