我有这个设置:
CREATE TABLE Stores
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](50) NOT NULL
);
CREATE TABLE Agents
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](200) NOT NULL,
[StoreID] [int] NULL
);
CREATE TABLE Sales
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[AgentID] [int] NOT NULL,
[Value] [money] NOT NULL
);
INSERT INTO Stores(Name) VALUES ('Paris');
INSERT INTO Stores(Name) VALUES ('New York');
INSERT INTO Stores(Name) VALUES ('Tokyo');
INSERT INTO Stores(Name) VALUES ('Rio de Janeiro');
INSERT INTO Agents (Name,StoreID) VALUES ('Michel', 1);
INSERT INTO Agents (Name,StoreID) VALUES ('Didier', 1);
INSERT INTO Agents (Name,StoreID) VALUES ('Gaston', 1);
INSERT INTO Agents (Name,StoreID) VALUES ('Mark', 2);
INSERT INTO Agents (Name,StoreID) VALUES ('Ben', 2);
INSERT INTO Agents (Name,StoreID) VALUES ('James', 2);
INSERT INTO Agents (Name,StoreID) VALUES ('Natsuo',3);
INSERT INTO Agents (Name,StoreID) VALUES ('Matheus',4);
INSERT INTO Sales (AgentID,Value) VALUES (1,500);
INSERT INTO Sales (AgentID,Value) VALUES (2,100);
INSERT INTO Sales (AgentID,Value) VALUES (3,200);
INSERT INTO Sales (AgentID,Value) VALUES (4,300);
INSERT INTO Sales (AgentID,Value) VALUES (5,250);
INSERT INTO Sales (AgentID,Value) VALUES (6,400);
INSERT INTO Sales (AgentID,Value) VALUES (7,200);
INSERT INTO Sales (AgentID,Value) VALUES (8,100);
INSERT INTO Sales (AgentID,Value) VALUES (1,500);
INSERT INTO Sales (AgentID,Value) VALUES (6,800);
INSERT INTO Sales (AgentID,Value) VALUES (3,1500);
INSERT INTO Sales (AgentID,Value) VALUES (2,50);
INSERT INTO Sales (AgentID,Value) VALUES (7,789);
INSERT INTO Sales (AgentID,Value) VALUES (5,230);
对于每个Store
,我希望通过一次查询获得平均销售总额,即获得最多和最少的代理商。
我知道如何使用单独的查询获取此信息,但我想使用单个查询。
这是我想要的输出:
New York | 660 | James | 1200 | Mark | 300
Paris | 950 | Gaston | 1700 | Didier | 150
Rio de Janeiro | 100 | Matheus | 100 | Matheus | 100
Tokyo | 989 | Natsuo | 989 | Natsuo | 989
这是我到目前为止所做的:
WITH AgentStats
AS (
SELECT Stores.NAME StoreName,
Agents.NAME AgentName,
SUM(Value) TotalValue
FROM Sales
LEFT JOIN Agents ON Agents.ID = Sales.AgentID
LEFT JOIN Stores ON Stores.ID = Agents.StoreID
GROUP BY Stores.NAME,
Sales.AgentID,
Agents.NAME
)
SELECT StoreName,
AVG(TotalValue),
MAX(TotalValue),
MIN(TotalValue)
FROM AgentStats
GROUP BY StoreName
谢谢!
答案 0 :(得分:0)
这似乎有效:
;With Totals as (
select
s.AgentID,
StoreID,
SUM(Value) as TotalSales
from
Agents a
inner join
Sales s
on
a.ID = s.AgentID
group by s.AgentID,
StoreID
), Ordered as (
select
AgentID,
StoreID,
TotalSales,
ROW_NUMBER() OVER (PARTITION BY StoreID ORDER BY TotalSales) as rnLow,
ROW_NUMBER() OVER (PARTITION BY StoreID ORDER BY TotalSales desc) as rnHigh,
AVG(TotalSales) OVER (PARTITION BY StoreID) as StoreAverage
from
Totals
)
select
st.Name,
o1.StoreAverage,
a1.Name,
o1.TotalSales,
a2.Name,
o2.TotalSales
from
Stores st
inner join
Ordered o1
on
st.ID = o1.StoreID and
o1.rnHigh = 1
inner join
Agents a1
on
o1.AgentID = a1.ID
inner join
Ordered o2
on
st.ID = o2.StoreID and
o2.rnLow = 1
inner join
Agents a2
on
o2.AgentID = a2.ID
结果:
Name StoreAverage Name TotalSales Name TotalSales
------------------- --------------------- --------- ------------ -------- ---------------------
Paris 950.00 Gaston 1700.00 Didier 150.00
New York 660.00 James 1200.00 Mark 300.00
Tokyo 989.00 Natsuo 989.00 Natsuo 989.00
Rio de Janeiro 100.00 Matheus 100.00 Matheus 100.00
这似乎符合您的要求。请注意,我们将其拆分为两个单独的CTE,我们首先计算单个代理总计,然后根据这些结果进行计算。
我们与ROW_NUMBER()
合作,因为您不仅仅想要找到销售的MIN
或MAX
值 - 您希望找到行,其中出现最小值或最大值。另外,因为我使用了ROW_NUMBER()
,如果顶部或底部位置存在平局,您将获得任意结果 - 其中一行将是行号1,其他行将被忽略。如果你需要处理关系,那么我们需要更多关于关系发生时应该做什么的规范。
答案 1 :(得分:0)
您可以将Rank()
函数添加到您的cte并将其加入自身:
WITH AgentStats
AS ( SELECT Stores.NAME StoreName ,
Agents.NAME AgentName ,
SUM(Value) TotalValue ,
RANK() OVER ( PARTITION BY Stores.name ORDER BY SUM(value) DESC ) AS highest ,
RANK() OVER ( PARTITION BY Stores.name ORDER BY SUM(value) ) AS lowest
FROM Sales
LEFT JOIN Agents ON Agents.ID = Sales.AgentID
LEFT JOIN Stores ON Stores.ID = Agents.StoreID
GROUP BY Stores.NAME ,
Sales.AgentID ,
Agents.NAME
)
SELECT as1.StoreName ,
AVG(as1.TotalValue) ,
as2.AgentName ,
MAX(as1.TotalValue) ,
as3.AgentName ,
MIN(as1.TotalValue)
FROM AgentStats as1
INNER JOIN AgentStats as2 ON as1.StoreName = as2.StoreName
AND as2.highest = 1
INNER JOIN AgentStats as3 ON as1.StoreName = as3.StoreName
AND as3.lowest = 1
GROUP BY as1.StoreName ,
as2.AgentName ,
as3.AgentName
答案 2 :(得分:0)
当你想表达获得最多的代理时,它就是
所以最终陈述是
WITH StoreAgent AS
(
SELECT dbo.Stores.Name AS StoreName, dbo.Agents.Name AS AgentName, SUM(Value) AS SumOfSales
FROM dbo.Stores
JOIN dbo.Agents ON dbo.Stores.ID = dbo.Agents.StoreID
JOIN dbo.Sales ON dbo.Agents.ID = dbo.Sales.AgentID
GROUP BY dbo.Stores.Name, dbo.Agents.Name
)
SELECT DISTINCT StoreName, AVG(SumOfSales) OVER (PARTITION BY StoreName),
FIRST_VALUE(AgentName) OVER (PARTITION BY StoreName ORDER BY SumOfSales DESC) AS AgentMost,
FIRST_VALUE(SumOfSales) OVER (PARTITION BY StoreName ORDER BY SumOfSales DESC) AS Most,
FIRST_VALUE(AgentName) OVER (PARTITION BY StoreName ORDER BY SumOfSales) AS AgentLeast,
FIRST_VALUE(SumOfSales) OVER (PARTITION BY StoreName ORDER BY SumOfSales) AS Least
FROM StoreAgent