根据角色类型从3个表中分层数据

时间:2013-10-04 07:35:00

标签: sql sql-server sql-server-2008 tsql

以下是我的表格:

[UserMaster]

UserId Int,UserName Varchar(200),AddedBy Int

UserId     EmpName           AddedBy
1          admin             0
2          SubAdmin1         1
3          Vikas             2
4          Mohit             3
5          Atul              4
6          Vishal            2
7          Mani              3
8          Sunny             1

[SalesMaster]

SalesId Int,UserId Int(FK_UserMaster_UserId),Price Int

SalesId  UserId    Price         StatusId
10        1        100         1 
11        2        200         1    
12        3        300         1
13        4        500         1
14        5        100             2
15        6        200             1
16        7        111             2
17        8        222             1

[SalesProducts]

SaleProductId Int,SaleId Int(FK_SaleMaster_SaleId),Quantity Int

SaleProductId    SalesId   Quantity

  1                10       2
  2                11       2
  3                12       1
  4                13       1
  5                14       3
  6                15       2
  7                16       5
  8                17       1

[输出]

结果集应该包含登录用户的销售额+他创建的用户以及他们创建的其他用户。

以下TotalSalesAmount是:

[SalesMaster] .Price * [SalesProducts] .Quantity

例如:UserId的总销售额:1是 100 * 2 + 200 * 2 + 300 * 1 + 500 * 1 + 100 * 3 + 200 * 2 + 111 * 5 + 222 * 1 = 2877

同样对于UserId:2是 200 * 2 + 300 * 1 + 200 * 2 + 500 * 1 + 111 * 5 + 200 * 2 = 2555

案例1:

如果(admin)UserId = 1将登录,我们需要显示以下

UserId     TotalSalesAmount    OwnSaleAmount           AddedBy

  1          2877         200               0

  2          2555         400               1

  3          1355             300               2

  4          800          500           3

  5          100*3= 300       300           4

  6          200*2=200        200           2

  7          111*5= 555       555               3

  8          222*1= 222       222           1

案例2: 如果(Vikas)UserId = 3将登录,我们需要显示以下

 UserId      TotalSalesAmount           OwnSaleAmount           AddedBy

  3          300*1 + 500*1 + 111*5= 1355            300                2

  4          500*1 + 100*3= 800                     500                3

  5          100*3= 300                         300            4

  7          111*5= 555                     555                3 

我在这里使用了表脚本和数据 http://test-admin.teamberry.biz/SalesScript.rar

运行此脚本后,请执行以下查询,取UM.UserId = 164,SM.statusID = 1 UserId = 166的TotalSalesAmount是错误的,因为它的TotalSaleAmount应该与ownSaleAmount相同,即444,因为UserId = 166没有任何子项。

with tblOwnSaleAmount as 
 ( 
      select UM.UserId,UM.EmpName,UM.AddedBy,cast(sum( SM.Price*SP.Quantity) as int) as OwnSaleAmount 
      from UserMaster UM
      left join SalesMaster SM on SM.UserId = UM.UserId  and SM.statusID = 1
      left join SalesProducts SP on SP.SalesId = SM.SalesId
      where UM.UserId = 164
      group by  UM.UserId ,UM.AddedBy,UM.EmpName 
      union all 
      select UM.UserId,UM.EmpName, UM.AddedBy, 
      case when SM.statusID = 1 then cast(( SM.Price*SP.Quantity ) as int)
      else 0 end as OwnSaleAmount
      from UserMaster UM
      join tblOwnSaleAmount on tblOwnSaleAmount.UserId = UM.AddedBy
      join SalesMaster SM on SM.UserId = UM.UserId 
      join SalesProducts SP on SP.SalesId = SM.SalesId 
 )
,  tbldistinctOwnSaleAmount as
 (
 select distinct UserId,EmpName, AddedBy,Isnull(OwnSaleAmount,0) as  OwnSaleAmount
 from tblOwnSaleAmount
 )
 ,

 tblTotalOwnSaleAmount as
 (
  select OSA.UserId,OSA.EmpName, OSA.AddedBy, sum( OSA.OwnSaleAmount ) as OwnSaleAmount
  from tbldistinctOwnSaleAmount OSA --inner join tbldistinctOwnSaleAmount A on OSA.AddedBy = A.UserID
  group by OSA.UserId ,OSA.AddedBy,OSA.EmpName
 )
 select OSA.* 
, TotalSalesAmount = isnull(
( 
    select sum( OSA1.OwnSaleAmount )
    from tblTotalOwnSaleAmount OSA1
    where OSA1.UserId > OSA.UserId 
), 0 )
+ OSA.OwnSaleAmount
 from tblTotalOwnSaleAmount OSA  
 order by OSA.UserId 

1 个答案:

答案 0 :(得分:1)

如果我的理解错误,请更新:

  1. 对于用户ID 3,您已采用TotalSalesAmount = 300 * 1 + 500 * 1 + 111 * 5(不包括用户ID 5的SaleAmount,而userID 5又由userID 4用户为用户ID 3创建)。所以TotalSalesAmount 对于userID 3应计算为:300 * 1 + 500 * 1 + 300 * 1 + 111 * 5 = 1655而非1355。
  2. 如果我的上述理解是正确的,您可以通过使用公用表表达式的递归功能获得所需的结果,然后计算运行总计:

    -- create a common table expression to get OwnSaleAmount for logged in user and all the users who are added由当前用户进一步提供。

     with tblOwnSaleAmount as 
     ( 
          select UM.UserId, UM.AddedBy, ( SM.Price*SP.Quantity ) as OwnSaleAmount 
          from UserMaster UM
          join SalesMaster SM on SM.UserId = UM.UserId 
          join SalesProducts SP on SP.SaleId = SM.SalesId 
          where UM.UserId = 1 -- Userid of logged in user which will act as anchor member 
                              -- for later subqueries
          union all 
    
          select UM.UserId, UM.AddedBy, ( SM.Price*SP.Quantity ) as OwnSaleAmount  
          from UserMaster UM
          join tblOwnSaleAmount on tblOwnSaleAmount.UserId = UM.AddedBy
          join SalesMaster SM on SM.UserId = UM.UserId 
          join SalesProducts SP on SP.SaleId = SM.SalesId 
    
     )
     select OSA.* 
    , TotalSalesAmount = isnull(
    ( 
        select sum( OSA1.OwnSaleAmount )
        from tblOwnSaleAmount OSA1
        where OSA1.AddedBy > = OSA.UserId                                                                   
    ), 0 )
    + OSA.OwnSaleAmount
     from tblOwnSaleAmount OSA
     order by OSA.UserId 
    

    编辑:更新了查询:

     --1. Corrected joins in anchor query to fetch records for users who have no records in SalesMaster Table.
     --2. IS it another requirement that user entries with status id = 2 should not be considered?
     with tblOwnSaleAmount as 
     ( 
          select UM.UserId, UM.AddedBy, sum( SM.Price*SP.Quantity ) as OwnSaleAmount 
          from UserMaster UM
          left join SalesMaster SM on SM.UserId = UM.UserId -- Missed requirement1
          left join SalesProducts SP on SP.SaleId = SM.SalesId -- Missed requirement1
          where UM.UserId = 2 -- Userid of logged in user which will act as anchor member 
          group by  UM.UserId ,UM.AddedBy                  -- for later subqueries
    
          union all 
    
          select UM.UserId, UM.AddedBy, ( SM.Price*SP.Quantity ) as OwnSaleAmount  
          from UserMaster UM
          join tblOwnSaleAmount on tblOwnSaleAmount.UserId = UM.AddedBy
          join SalesMaster SM on SM.UserId = UM.UserId 
          join SalesProducts SP on SP.SaleId = SM.SalesId 
    
     ),
      tbldistinctOwnSaleAmount as
     (
     select distinct UserId, AddedBy, OwnSaleAmount 
     from tblOwnSaleAmount
     ) ,
     tblTotalOwnSaleAmount as
     (
      select OSA.UserId,OSA.AddedBy, sum( OSA.OwnSaleAmount ) as OwnSaleAmount
      from tbldistinctOwnSaleAmount OSA
      group by OSA.UserId ,OSA.AddedBy
     )
     select OSA.* 
    , TotalSalesAmount = isnull(
    ( 
        select sum( OSA1.OwnSaleAmount )
        from tblTotalOwnSaleAmount OSA1
        where OSA1.UserId > OSA.UserId                                                                   
    ), 0 )
    + OSA.OwnSaleAmount
     from tblTotalOwnSaleAmount OSA
     order by OSA.UserId 
    

    希望这有帮助!!!

    [EDIT2]:更新了错过要求2的查询:

     --2. IS it another requirement that user entries with status id = 2 should not be considered? -- Yes!!!
     with tblOwnSaleAmount as 
     ( 
          select UM.UserId, UM.AddedBy, sum( SM.Price*SP.Quantity ) as OwnSaleAmount 
          from UserMaster UM
          left join SalesMaster SM on SM.UserId = UM.UserId  and SM.statusID = 1-- Missed requirement1 and 2
          left join SalesProducts SP on SP.SaleId = SM.SalesId -- Missed requirement1
          where UM.UserId = 2 -- Userid of logged in user which will act as anchor member 
          group by  UM.UserId ,UM.AddedBy                  -- for later subqueries
    
          union all 
    
          select UM.UserId, UM.AddedBy, 
          case when SM.statusID = 1 then ( SM.Price*SP.Quantity ) 
          else 0 end as OwnSaleAmount  --Missed Requirement 2.
          from UserMaster UM
          join tblOwnSaleAmount on tblOwnSaleAmount.UserId = UM.AddedBy
          join SalesMaster SM on SM.UserId = UM.UserId 
          join SalesProducts SP on SP.SaleId = SM.SalesId 
    
     ),
      tbldistinctOwnSaleAmount as
     (
     select distinct UserId, AddedBy, OwnSaleAmount 
     from tblOwnSaleAmount
     ) ,
     tblTotalOwnSaleAmount as
     (
      select OSA.UserId,OSA.AddedBy, sum( OSA.OwnSaleAmount ) as OwnSaleAmount
      from tbldistinctOwnSaleAmount OSA
      group by OSA.UserId ,OSA.AddedBy
     )
     select OSA.* 
    , TotalSalesAmount = isnull(
    ( 
        select sum( OSA1.OwnSaleAmount )
        from tblTotalOwnSaleAmount OSA1
        where OSA1.UserId > OSA.UserId                                                                   
    ), 0 )
    + OSA.OwnSaleAmount
     from tblTotalOwnSaleAmount OSA
     order by OSA.UserId 
    

    要获得正确的结果,您需要更新锚表的on谓词,然后为其他递归表添加case语句。