Sql server 将选定值除以计数(*)

Sql server 将选定值除以计数(*),sql-server,tsql,Sql Server,Tsql,我有一个Microsoft SQL Server,其中包含以下表格: 计划 BookedHours(fk_Project=Projects.ID) 产品 ProjectStopProducts(n:m,其中fk_Projects=Projects.ID,fk_Products=Products.ID) 现在我想选择每月为哪个产品预订多少小时。问题是,一个项目可以有多个产品(这就是为什么我需要n:m表) 如果我执行以下操作,那么如果一个项目有两个产品,它将计算两次时间 SELECT

我有一个Microsoft SQL Server,其中包含以下表格:

  • 计划
  • BookedHours(fk_Project=Projects.ID)
  • 产品
  • ProjectStopProducts(n:m,其中fk_Projects=Projects.ID,fk_Products=Products.ID)
现在我想选择每月为哪个产品预订多少小时。问题是,一个项目可以有多个产品(这就是为什么我需要n:m表)

如果我执行以下操作,那么如果一个项目有两个产品,它将计算两次时间

SELECT 
    P.ID AS fk_Product, MONTH(B.Datum) AS Monat, SUM(B.Hours) AS Stunden
FROM 
    tbl_BookedHours AS B 
INNER JOIN 
    tbl_Projects AS M on B.fk_Project = M.ID            
INNER JOIN 
    tbl_ProjectProduct AS PP ON PP.fk_Project = M.ID
INNER JOIN 
    tbl_Products AS P ON PP.fk_Product = P.ID               
WHERE 
    YEAR(B.Datum) = 2020
GROUP BY 
    P.ID, MONTH(B.Datum)
ORDER BY 
    P.ID, MONTH(B.Datum)
我可以通过以下SQL获取每个项目的产品数量:

SELECT fk_Project, COUNT(*) AS Cnt
FROM tbl_ProjectProduct
GROUP By fk_MainProject
但是,我现在如何将每个项目的小时数除以各个因素,然后将每个产品和月份的小时数相加呢

我可以在我的C#程序中完成,也可以使用游标遍历所有项目,但我认为应该有一种更优雅的方式

使用样本数据编辑

|----------------|   |----------------|   |------------------------------| 
| tbl_Projects   |   | tbl_Products   |   | tbl_ProjectProduct           |
|----------------|   |----------------|   |------------------------------|
| ID | Name      |   | ID | Name      |   | ID | fk_Project | fk_Product |
|----+-----------|   |----+-----------|   |------------------------------|
|  1 | Project 1 |   |  1 | Product 1 |   |  1 | 1          | 1          |
|  2 | Project 2 |   |  2 | Product 2 |   |  2 | 1          | 2          |
|  3 | Project 3 |   |  3 | Product 3 |   |  3 | 2          | 1          |
|  4 | Project 4 |   |  4 | Product 4 |   |  4 | 3          | 3          |
|----------------|   |----------------|   |  5 | 4          | 1          |
                                          |  6 | 4          | 2          |
                                          |  7 | 4          | 4          |
                                          |------------------------------|

|--------------------------------------|
| tbl_BookedHours                      |
|--------------------------------------|
| ID | fk_Project | Hours | Date       |
|--------------------------------------|
|  1 | 1          | 10    | 2020-01-15 |
|  2 | 1          | 20    | 2020-01-20 |
|  3 | 2          | 10    | 2020-01-15 |
|  4 | 3          | 30    | 2020-01-18 |
|  5 | 2          | 20    | 2020-01-20 |
|  6 | 4          | 30    | 2020-01-25 |
|  7 | 1          | 10    | 2020-02-15 |
|  8 | 1          | 20    | 2020-02-20 |
|  9 | 2          | 10    | 2020-02-15 |
| 10 | 3          | 30    | 2020-03-18 |
| 11 | 2          | 20    | 2020-03-20 |
| 12 | 4          | 30    | 2020-03-25 |
|--------------------------------------|
结果应该是:

|----------------------------|
| fk_Product | Month | Hours |
|----------------------------|
| 1          | 1     | 55    |
| 2          | 1     | 25    |
| 3          | 1     | 30    |
| 4          | 1     | 10    |
| 1          | 2     | 25    |
| 2          | 2     | 15    |
| 1          | 3     | 30    |
| 2          | 3     | 10    |
| 3          | 3     | 30    |
| 4          | 3     | 10    |
|----------------------------|
例如,1号预订必须除以2(因为项目1有两个产品),并将金额的一半添加到产品1,另一半添加到产品2(均在1月份)。4号预订不应分割,因为项目3只有一个产品。例如,预订编号12必须除以3。 所以最后的总小时数加起来是一样的。 我希望现在更清楚了。 ***编辑2***

DECLARE @tbl_Projects TABLE (ID INT, [Name] VARCHAR(MAX))
INSERT INTO @tbl_Projects VALUES
(1,'Project 1'),
(2,'Project 2'),
(3,'Project 3'),
(4,'Project 4')

DECLARE @tbl_Products TABLE (ID INT, [Name] VARCHAR(MAX))
INSERT INTO @tbl_Products VALUES
(1,'Product 1'),
(2,'Product 2'),
(3,'Product 3'),
(4,'Product 4')

DECLARE @tbl_ProjectProduct TABLE (ID INT, fk_Project int, fk_Product int)
INSERT INTO @tbl_ProjectProduct VALUES
(1,1,1),
(2,1,2),
(3,2,1),
(4,3,3),
(5,4,1),
(6,4,2),
(7,4,4)

DECLARE @tbl_BookedHours TABLE (ID INT, fk_Project int, Hours int, [Date] Date)
INSERT INTO @tbl_BookedHours VALUES
(1,1,10,'2020-01-15'),
(2,1,20,'2020-01-20'),
(3,2,10,'2020-01-15'),
(4,3,30,'2020-01-18'),
(5,2,20,'2020-01-20'),
(6,4,30,'2020-01-25'),
(7,1,10,'2020-02-15'),
(8,1,20,'2020-02-20'),
(9,2,10,'2020-02-15'),
(10,3,30,'2020-03-18'),
(11,2,20,'2020-03-20'),
(12,4,30,'2020-03-25')

SELECT P.ID AS fk_Product, MONTH(B.Date) AS Month, SUM(B.Hours) AS SumHours
    FROM @tbl_BookedHours AS B INNER JOIN @tbl_Projects AS M on B.fk_Project = M.ID           
                                INNER JOIN @tbl_ProjectProduct AS PP ON PP.fk_Project = M.ID
                                INNER JOIN @tbl_Products AS P ON PP.fk_Product = P.ID                
    GROUP BY P.ID,MONTH(B.Date)
    ORDER BY P.ID, MONTH(B.Date)
这给了我错误的结果,因为它计算了两种产品的小时数:

| fk_Product | Month | SumHours |
|-------------------------------|
| 1          | 1     | 90       |
| 1          | 2     | 40       |
| 1          | 3     | 50       |
| 2          | 1     | 60       |
| 2          | 2     | 30       |
| 2          | 3     | 30       |
| 3          | 1     | 30       |
| 3          | 3     | 30       |
| 4          | 1     | 30       |
| 4          | 3     | 30       |
|-------------------------------|

考虑以下查询。我将您的表变量修改为临时表,以便更容易调试

;WITH CTE AS
    (
    SELECT fk_Project, count(fk_Product) CNT 
    FROM #tbl_ProjectProduct
    GROUP BY fk_Project
    )
    ,CTE2 AS
        (
        SELECT t1.Date, t2.fk_Project, Hours/CNT NewHours
        FROM #tbl_BookedHours t1
        INNER JOIN CTE t2 on t1.fk_Project = t2.fk_Project
        )
SELECT t4.ID fk_Product, MONTH(date) MN, SUM(NewHours) HRS
FROM CTE2 t1
INNER JOIN #tbl_Projects t2 on t1.fk_Project = t2.id
INNER JOIN #tbl_ProjectProduct t3 on t3.fk_Project = t2.ID
INNER JOIN #tbl_Products t4 on t4.ID = t3.fk_Product
GROUP BY t4.ID,MONTH(date)

嗨,Suiram,我同意肯定有一种更优雅的方式。您能否提供一些示例数据,以便我们更好地了解如何帮助您解决问题?谢谢