Sql server 如何仅在SQL Server数据库表中的整型字段的值发生变化时才递增该字段?
我有一个整数字段,本质上是sql server表中一个名为“项目”的计数器,我只想在另一个字段的值更改时增加它。对于所有行,初始PID=1。下面的查询是我从你在别处的一个答案中得到的,它正是我想要的,但是我需要用结果更新我的表,我无法理解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
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;