Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 如何仅在SQL Server数据库表中的整型字段的值发生变化时才递增该字段?_Sql Server - Fatal编程技术网

Sql server 如何仅在SQL Server数据库表中的整型字段的值发生变化时才递增该字段?

Sql server 如何仅在SQL Server数据库表中的整型字段的值发生变化时才递增该字段?,sql-server,Sql Server,我有一个整数字段,本质上是sql server表中一个名为“项目”的计数器,我只想在另一个字段的值更改时增加它。对于所有行,初始PID=1。下面的查询是我从你在别处的一个答案中得到的,它正是我想要的,但是我需要用结果更新我的表,我无法理解 SELECT Task, dense_rank() over(order by Task) PID FROM dbo.Projects; 如果我做了类似的事情 Update Projects SET Projects.PID =(SELECT Task

我有一个整数字段,本质上是sql server表中一个名为“项目”的计数器,我只想在另一个字段的值更改时增加它。对于所有行,初始PID=1。下面的查询是我从你在别处的一个答案中得到的,它正是我想要的,但是我需要用结果更新我的表,我无法理解

SELECT Task,
  dense_rank() over(order by Task)  PID
FROM dbo.Projects;
如果我做了类似的事情

Update Projects
SET Projects.PID =(SELECT Task,
  dense_rank() over(order by Task)  PID
FROM dbo.Projects);
我得到的INSERT语句的select列表包含的项目比INSERT列表多。SELECT值的数量必须与INSERT列的数量匹配。我如何用一个查询更新我的表,从而得到我想要的

这是表格设计:

CREATE TABLE [dbo].[Projects]
( 
    [PID] [int] NULL
    , [TID] [int] IDENTITY(1,1) NOT NULL
    , [Project] [nvarchar](127) NOT NULL
    , [Task] [nvarchar](127) NOT NULL
    , [Dollars] [decimal](18, 0) NOT NULL
    , [TaskLead] [nvarchar](127) NULL 
) ON [PRIMARY];
我用

INSERT INTO dbo.Projects(Project, Task, Dollars, TaskLead) 
SELECT Project + ' ' + ProjectDescription, Task + ' ' + TaskDescription, Dollars, TaskLead 
FROM TM1_1 
ORDER BY Project ASC, Task ASC;
例如,数据:

PID     TID     Project     Task 
1       1       Prj1        Tsk11 
1       2       Prj1        Tsk12 
2       1       Prj2        Tsk21
我想更新该表,以便所有相同的项目都具有相同的PID。我现在正在尝试:

use mbt_tm1; 
;WITH cteRank AS (
     SELECT PID, DENSE_RANK() OVER ( PARTITION BY Project ORDER BY Project ASC) AS Calculated_Rank 
    FROM Projects ) 
UPDATE cteRank 
SET PID = Calculated_Rank

您只需从内部查询返回一个值,并且您正在查找排名:

Update Projects
SET Projects.PID = X.Calculated_Rank
FROM Project P
INNER JOIN 
    (SELECT P1.PID, DENSE_RANK() OVER ( PARTITION BY P1.Project ORDER BY P1.Project ASC) AS Calculated_Rank 
    FROM Projects P1) X
ON X.PID = P.PID

如果不知道更多关于你的确切问题,也许这会起作用

Update Projects
SET Projects.PID = dense_rank() over(order by Task);
为了帮助回答你的问题,我收集了一个小样本,我认为它能说明你的问题。如果这不反映您的环境,请在问题中添加详细信息

CREATE TABLE Projects 
(
    ProjectID INT
    , Task INT
    , PID INT
);
GO

INSERT INTO Projects (ProjectID, Task, PID) VALUES (1, 1, 1);
INSERT INTO Projects (ProjectID, Task, PID) VALUES (2, 1, 2);
INSERT INTO Projects (ProjectID, Task, PID) VALUES (3, 1, 3);
INSERT INTO Projects (ProjectID, Task, PID) VALUES (4, 2, 1);

UPDATE Projects
SET Projects.PID = (
    SELECT MAX(PID) + 1
    FROM Projects p 
    WHERE P.Task = Projects.Task
);

SELECT *
FROM Projects;
[编辑2]

除非我误解了您的要求,否则这似乎是更新所有相关项目PID的简单方法:

UPDATE Projects
SET PID = (SELECT MAX(PID) FROM Projects P WHERE P.Project = Projects.Project);

很抱歉,你的问题很不清楚。然而,您所说的原始SELECT查询对您有效,您希望将其用于更新,我发现更新是错误的。 正确的更新syntex应该是这样的

使用任务匹配的新列组更新表中的PID

编辑:-1 此查询将获得示例中所解释和显示的输出

不需要使用CTE

    set nocount on
    declare @prj table
    (
        pid     int null
        ,tid    int null
        ,prj    sysname
        ,tsk    sysname

    )
    insert into @prj (prj,tsk)
    select 'prj1','tsk11' 
    union all select 'prj1','tsk12' 
    union all select 'prj2','tsk21'
    union all select 'prj2','tsk22'

    update t1 set t1.pID=t2.pID, t1.tID=t2.tID
    from @prj t1
    join
    (

        select  dense_RANK() over (order by prj) as pID
                ,ROW_NUMBER() over (partition by prj order by prj,tsk) as tID
                ,prj,tsk
        from @prj
    )t2
        on t1.prj=t2.prj and t1.tsk=t2.tsk

    select * from @prj
这就是成功的原因:

;WITH cte AS (
   SELECT PID,
      DENSE_RANK() OVER (
         ORDER BY Project ASC) AS Calculated_Rank
   FROM Projects
)
UPDATE cte SET PID = Calculated_Rank
它转换了一个显示结果的查询,即:

SELECT Project,
  dense_rank() over(order by Project)  PID
FROM dbo.Projects;

变成一个实际更新表的。非常感谢您的支持

你需要更清楚你真正想要什么。与其他任务相比,是否希望PID列是其任务的密集_秩?请注意,这个数字将根据任务列的排序顺序向上/向下移动。我只知道具有稠密_秩的查询有效。我想要的是更新我的表,以便获得,例如,PID TID项目任务1 1 Prj1 Tsk11 2 Prj1 Tsk12 1 Prj2 Tsk21等。我从另一个渠道得到了Prj和Tsk的。我需要根据这个模式添加PID和TID。我不依附于高等级。当我在查询中使用它时,我只知道它做了我想要的。不幸的是,没有,我得到:Msg 4108,级别15,状态1,第2行窗口函数只能出现在SELECT或ORDER BY子句中。也许我需要用游标来做这件事,但我对游标不太熟悉。我可以帮你做这件事,但如果你编辑你的问题来显示实际的表设计,以及两行示例数据和示例所需的结果,这将真的对我有帮助。下面是表设计:使用[MBT_TM1]GO/*******对象:表[dbo]。[项目]脚本日期:2013年10月15日19:03:51***/SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE TABLE[dbo].[Projects][PID][int]NULL[TID][int]IDENTITY1,1 NOT NULL[Project][nvarchar 127 NOT NULL[Task][nvarchar 127 NOT NULL][decimal decimal 18,0 NOT NULL[TaskLead][nvarcharchar 127 NOT PRIMARY]呃,我希望你能理解这个设计。我用INSERT INTO dbo.projects项目,任务,美元,任务领导选择项目+“”+项目描述,任务+“”+任务描述,美元,任务领导从TM1_1按项目ASC,任务ASC排序;然后我想更新表,使所有相同的项目都有相同的PID。我现在正在尝试:使用mbt_tm1;;使用CTRANK作为选择PID,按项目顺序按项目ASC作为计算的分区进行密集排序从项目更新CTRANK SET PID=COMPUTED_RANK,没有错误,但PID值仅为1。我真的非常感谢您的帮助。不幸的是,没有,我得到:Msg 512,16级,状态1,第2行子查询返回了多个值。当子查询后跟=、!=、=或子查询用作表达式时,不允许这样做。语句已终止。我想我需要不同的方法,但我不确定这是什么。不幸的是,它没有达到我想要的效果。我在我假设PID列为最大值,但这不是我想要的。如果我执行以下查询:SELECT Project,DEGRENCE_rank overorder by Project PID FROM dbo.Projects;我看到了我想要的,但我需要用这些结果更新表。我非常感谢您的帮助,这是我迫切需要的。最后一次尝试-请检查我的情况完全一样,但对那个人有效的东西对我无效。我真的很感激
help.根据您的需要更新查询。不需要CTE。请参阅Edit-1下的代码。CTE似乎工作得很好。有什么理由不使用它吗?没什么错,只是说,如果查询可以不使用它而编写,你应该去做。
SELECT Project,
  dense_rank() over(order by Project)  PID
FROM dbo.Projects;