Sql 帮助查询

Sql 帮助查询,sql,sql-server,sql-server-2005,tsql,Sql,Sql Server,Sql Server 2005,Tsql,根据下表 ID Effort Name ------------------------- 1 1 A 2 1 A 3 8 A 4 10 B 5 4 B 6 1 B 7 10 C 8 3 C 9 30

根据下表

ID      Effort      Name
-------------------------
1       1           A
2       1           A
3       8           A
4       10          B
5       4           B
6       1           B
7       10          C
8       3           C
9       30          C
我想检查一个名称的总工作量是否小于40,然后为该名称添加一行工作量=40-(总工作量)。新行的ID可以是任何内容。如果总工作量大于40,则构建其中一行的数据,使其为40

因此,在应用上述逻辑后,表将

ID      Effort      Name
-------------------------
1       1           A
2       1           A
3       8           A
10      30          A

4       10          B
5       4           B
6       1           B
11      25          B

7       10          C
8       3           C
9       27          C
我想打开一个游标,保留一个总工作量的计数器,并根据逻辑在另一个临时表中插入现有行和新行


我不确定这是否是一种有效的处理方法。我想了解是否有更好的方法。

这将为您提供需要修改的名称:

SELECT Name, SUM(Effort)
FROM Table
GROUP BY Name
HAVING SUM(Effort) < 40
选择名称、总和(工作量)
从桌子上
按名称分组
总(努力)少于40

将其选择到临时表中,为40-SUM添加一列,然后根据该列创建insert语句。比光标要好得多。

这将为您提供需要修改的名称:

SELECT Name, SUM(Effort)
FROM Table
GROUP BY Name
HAVING SUM(Effort) < 40
选择名称、总和(工作量)
从桌子上
按名称分组
总(努力)少于40

将其选择到临时表中,为40-SUM添加一列,然后根据该列创建insert语句。比光标要好得多。

我认为第一部分可以这样做:

 INSERT INTO tbl(Effort, Name)
 SELECT 40 - SUM(Effort), Name
 FROM tbl
 GROUP BY Name
 HAVING SUM(Effort) < 40) 
插入tbl(工作量、名称)
选择40-总和(工作量),名称
来自tbl
按名称分组
有总和(努力)<40)
第二部分比较难。也许你可以这样做

 INSERT INTO tbl(Effort, Name)
 SELECT 40 - SUM(Effort), Name
 FROM tbl
 GROUP BY Name
 HAVING SUM(Effort) <> 40) 
插入tbl(工作量、名称)
选择40-总和(工作量),名称
来自tbl
按名称分组
有总和(努力)40)

这样做的目的是,如果总工作时间>40小时,则添加一行,名称为负数;如果总工作时间<40小时,则为正值,而不是更改实际数据。对于数据完整性而言,这似乎比破坏原始值要安全得多。

我认为第一部分可以这样做:

 INSERT INTO tbl(Effort, Name)
 SELECT 40 - SUM(Effort), Name
 FROM tbl
 GROUP BY Name
 HAVING SUM(Effort) < 40) 
This will do the first part:

Insert Into dbo.Test (Name, Effort)
Select t.Name, 40 - SUM(t.Effort)
From dbo.Test t
Group By t.Name
Having SUM(t.Effort) < 40
插入tbl(工作量、名称)
选择40-总和(工作量),名称
来自tbl
按名称分组
有总和(努力)<40)
第二部分比较难。也许你可以这样做

 INSERT INTO tbl(Effort, Name)
 SELECT 40 - SUM(Effort), Name
 FROM tbl
 GROUP BY Name
 HAVING SUM(Effort) <> 40) 
插入tbl(工作量、名称)
选择40-总和(工作量),名称
来自tbl
按名称分组
有总和(努力)40)

这样做的目的是,如果总工作时间>40小时,则添加一行,名称为负数;如果总工作时间<40小时,则为正值,而不是更改实际数据。对于数据完整性而言,这似乎比破坏原始值要安全得多。

SQL Server 2008
中,这可以通过一条
合并
语句完成:

This will do the first part:

Insert Into dbo.Test (Name, Effort)
Select t.Name, 40 - SUM(t.Effort)
From dbo.Test t
Group By t.Name
Having SUM(t.Effort) < 40
DECLARE @efforts TABLE (id INT NOT NULL PRIMARY KEY, effort INT NOT NULL, name CHAR(1))

INSERT
INTO    @efforts
VALUES  (1, 1, 'A'),
        (2, 1, 'A'),
        (3, 8, 'A'),
        (4, 10, 'B'),
        (5, 4, 'B'),
        (6, 1, 'B'),
        (7, 10, 'C'),
        (8, 3, 'C'),
        (9, 30, 'C'),
        (10, 60, 'C')

SELECT  *
FROM    @efforts
ORDER BY
        name, id

;WITH    total AS
        (       SELECT  *
                FROM    @efforts e
                UNION ALL
                SELECT  ROW_NUMBER() OVER(ORDER BY name) +
                        (
                        SELECT  MAX(id)
                        FROM    @efforts
                        ),
                        40 - SUM(effort),
                        name
                FROM    @efforts
                GROUP BY
                        name
                HAVING  SUM(effort) < 40
        ),
        source AS
        (
        SELECT  *,
                (
                SELECT  SUM(effort)
                FROM    total ep
                WHERE   ep.name = e.name
                        AND ep.id <= e.id
                ) AS ce,
                COALESCE(
                (
                SELECT  SUM(effort)
                FROM    total ep
                WHERE   ep.name = e.name
                        AND ep.id < e.id
                ), 0) AS cp
        FROM    total e
        )
MERGE
INTO    @efforts e
USING   source s
ON      e.id = s.id
WHEN MATCHED AND 40 BETWEEN cp AND ce THEN
UPDATE
SET     e.effort = s.effort + 40 - ce
WHEN MATCHED AND cp > 40 THEN
DELETE
WHEN NOT MATCHED BY TARGET THEN
INSERT  (id, effort, name)
VALUES  (id, effort, name);

SELECT  *
FROM    @efforts
ORDER BY
        name, id

SQL Server 2008
中,这可以通过单个
MERGE
语句完成:

DECLARE @efforts TABLE (id INT NOT NULL PRIMARY KEY, effort INT NOT NULL, name CHAR(1))

INSERT
INTO    @efforts
VALUES  (1, 1, 'A'),
        (2, 1, 'A'),
        (3, 8, 'A'),
        (4, 10, 'B'),
        (5, 4, 'B'),
        (6, 1, 'B'),
        (7, 10, 'C'),
        (8, 3, 'C'),
        (9, 30, 'C'),
        (10, 60, 'C')

SELECT  *
FROM    @efforts
ORDER BY
        name, id

;WITH    total AS
        (       SELECT  *
                FROM    @efforts e
                UNION ALL
                SELECT  ROW_NUMBER() OVER(ORDER BY name) +
                        (
                        SELECT  MAX(id)
                        FROM    @efforts
                        ),
                        40 - SUM(effort),
                        name
                FROM    @efforts
                GROUP BY
                        name
                HAVING  SUM(effort) < 40
        ),
        source AS
        (
        SELECT  *,
                (
                SELECT  SUM(effort)
                FROM    total ep
                WHERE   ep.name = e.name
                        AND ep.id <= e.id
                ) AS ce,
                COALESCE(
                (
                SELECT  SUM(effort)
                FROM    total ep
                WHERE   ep.name = e.name
                        AND ep.id < e.id
                ), 0) AS cp
        FROM    total e
        )
MERGE
INTO    @efforts e
USING   source s
ON      e.id = s.id
WHEN MATCHED AND 40 BETWEEN cp AND ce THEN
UPDATE
SET     e.effort = s.effort + 40 - ce
WHEN MATCHED AND cp > 40 THEN
DELETE
WHEN NOT MATCHED BY TARGET THEN
INSERT  (id, effort, name)
VALUES  (id, effort, name);

SELECT  *
FROM    @efforts
ORDER BY
        name, id

截断行似乎未指定-应选择哪一行进行缩减?是否可以删除行以满足条件?您可以选择多行吗?(即,假设您有42个条目,每个条目的工作量为1)如果没有一行可以被您使用的值截断,您希望做什么?如果你有45行,都是1行?现在,这不仅是一个更新/插入查询,而且是一个删除?是的,行也可以删除。因此,如果总工作量为42小时,有42个条目。可以删除最后2个条目。截断条目似乎未指定-应选择减少哪一行?是否可以删除行以满足条件?您可以选择多行吗?(即,假设您有42个条目,每个条目的工作量为1)如果没有一行可以被您使用的值截断,您希望做什么?如果你有45行,都是1行?现在,这不仅是一个更新/插入查询,而且是一个删除?是的,行也可以删除。因此,如果总工作量为42小时,有42个条目。最后2个条目可以删除。感谢您的解决方案。我正在得到结果,但现在的问题是如何删除超过40小时的行。i、 应用你提到的第二个查询,我得到一个20 A 10 A 20 A 20 A-30,我希望结果是20 A 10 A 10[删除一行,最后一行被截断10],所以现在总数是40。这可以做到吗?谢谢你的解决方案。我正在得到结果,但现在的问题是如何删除超过40小时的行。i、 应用你提到的第二个查询,我得到一个20 A 10 A 20 A 20 A-30,我希望结果是20 A 10 A 10[删除一行,最后一行被截断10],所以现在总数是40。这能做到吗?我的错。我连接到一个2005年的数据库。它在“合并”错误附近给了我错误的语法。2005年是否有使用合并的解决方案?Thanks@stackoverflowuser:一句话也没有。我的错。我连接到一个2005年的数据库。它在“合并”错误附近给了我错误的语法。2005年是否有使用合并的解决方案?Thanks@stackoverflowuser:不使用单个语句。