Sql server 从另一个查询的结果进行查询

Sql server 从另一个查询的结果进行查询,sql-server,tsql,Sql Server,Tsql,我正在尝试创建一个查询,根据销售额列出前150种产品以及每种产品的前10位客户。我可以创建两个查询,第一个是基于销售额$150的前150个产品,另一个是按产品列出的每个客户的总销售额,但我如何将它们组合到一个查询中,以便结果将有1500条记录,显示前150个产品中每个产品的前10个客户 首先是客户销售排名 SELECT product_ID, custno, Total_Sales, RANK() OVER (ORDER BY Total_Sales DESC) AS

我正在尝试创建一个查询,根据销售额列出前150种产品以及每种产品的前10位客户。我可以创建两个查询,第一个是基于销售额$150的前150个产品,另一个是按产品列出的每个客户的总销售额,但我如何将它们组合到一个查询中,以便结果将有1500条记录,显示前150个产品中每个产品的前10个客户

首先是客户销售排名

SELECT     
    product_ID, custno, Total_Sales, 
    RANK() OVER (ORDER BY Total_Sales DESC) AS Sale_Rank_byCust
FROM  
    (SELECT  
         product_ID, custno, SUM(Sales$) AS Total_Sales
     FROM    
         dbo.SalesDetails
     WHERE   
         invdte >= GETDATE() - 1095
     GROUP BY 
         product_ID, custno) AS B
第二个是销售额排名前150的产品$

SELECT TOP 150 
    product_ID, T_Extprice, 
    RANK() OVER (ORDER BY T_Extprice DESC) AS SalesRank
FROM  
    (SELECT 
         product_ID, SUM(Sales$) AS T_Extprice, product
     FROM  
         dbo.SalesDetails AS SD
     GROUP BY 
         product_ID) AS A

你应该能够像这样使用外部应用程序

select      *
from        (
                select      top 150 
                            product_ID, 
                            SUM(Sales$) AS Total_Sales
                from        dbo.SalesDetails sd1
                group by    product_ID
                order by    Total_Sales desc
            ) p
outer apply (
                select      top 10
                            custno,
                            SUM(Sales$) AS Total_Sales
                from        dbo.SalesDetails sd2
                where       sd2.product_ID = p.product_ID
                and         sd2.invdte >= GETDATE() - 1095
                group by    custno
                order by    Total_Sales desc

            ) c

您可能可以使用单个派生表来完成此操作,并以不同的方式对两个列组进行分区

您应该能够像这样使用外部应用来完成此操作

select      *
from        (
                select      top 150 
                            product_ID, 
                            SUM(Sales$) AS Total_Sales
                from        dbo.SalesDetails sd1
                group by    product_ID
                order by    Total_Sales desc
            ) p
outer apply (
                select      top 10
                            custno,
                            SUM(Sales$) AS Total_Sales
                from        dbo.SalesDetails sd2
                where       sd2.product_ID = p.product_ID
                and         sd2.invdte >= GETDATE() - 1095
                group by    custno
                order by    Total_Sales desc

            ) c

您可能可以使用单个派生表来完成此操作,并以不同的方式对两个列组进行分区

对于这样的事情,我使用窗口函数。以下是一种方法:

select pc.*
from (select pc.*,
             dense_rank() over (order by product_sales desc, product_id) as product_rank
      from (select sd.product_id, sd.custno, sum(sd.sales$) as total_sales,
                   row_number() over (partition by sd.product_id order by sum(sd.sales$) as cust_within_product_rank,
                   sum(sum(sd.sales$)) over (partition by sd.product_id) as product_sales
            from salesdetails sd
            group by sd.product_id, sd.custno
           ) pc
      ) pc
where product_rank <= 150 and cust_within_product_rank <= 10;

我转向窗口函数来处理类似的事情。以下是一种方法:

select pc.*
from (select pc.*,
             dense_rank() over (order by product_sales desc, product_id) as product_rank
      from (select sd.product_id, sd.custno, sum(sd.sales$) as total_sales,
                   row_number() over (partition by sd.product_id order by sum(sd.sales$) as cust_within_product_rank,
                   sum(sum(sd.sales$)) over (partition by sd.product_id) as product_sales
            from salesdetails sd
            group by sd.product_id, sd.custno
           ) pc
      ) pc
where product_rank <= 150 and cust_within_product_rank <= 10;

你可以试试交叉连接

select top 105 * from salesTable where <as you wish>
cross join 
select top 10 * from customerTable where <as you wish>

你可以试试交叉连接

select top 105 * from salesTable where <as you wish>
cross join 
select top 10 * from customerTable where <as you wish>

将top 150作为派生表作为锚定,并交叉应用于每个产品的top 10。将top 150作为派生表作为锚定,并交叉应用于每个产品的top 10。戈登,感谢您的解决方案。这很有效。如果我需要根据invdte发票日期设置两个不同的条件,其中前150个产品排名来自最近10年的销售,而产品排名中的客户排名则基于最近3年的销售,我如何修改此查询以接受两个不同的日期?@vinnynh。我想你应该问另一个问题。戈登,谢谢你的解决方案。这很有效。如果我需要根据invdte发票日期设置两个不同的条件,其中前150个产品排名来自最近10年的销售,而产品排名中的客户排名则基于最近3年的销售,我如何修改此查询以接受两个不同的日期?@vinnynh。我想你应该问另一个问题。