0

Projects という名前の SQL Server テーブルに PID という整数フィールド (基本的にはカウンター) があり、別のフィールド (タスク) の値が変更された場合にのみインクリメントしたいと考えています。最初は、すべての行で PID=1 です。次のクエリ(他の場所での回答の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 列の数と一致する必要があります。」というメッセージが表示されます。必要なものを提供するクエリでテーブルを更新するにはどうすればよいですか?

これはテーブルのデザインです:

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
4

4 に答える 4

0

内部クエリから値を 1 つだけ返す必要があり、ランクを探しています。

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
于 2013-10-15T03:56:35.157 に答える
0

申し訳ありませんが、あなたの質問は非常に不明確です。それでも、あなたが言った元の SELECT クエリは機能しており、それを更新に使用したいのですが、更新が間違っていることがわかりました。正しい更新構文は次のようになります。

タスクが一致する新しいランクでテーブルの PID を更新します。

    UPDATE  t1 SET t1.Projects.PID = t2.pid
    FROM Projects t1
    JOIN
    ( 
        SELECT Task ,DENSE_RANK() OVER ( ORDER BY Task ) PID
        FROM   Projects
    )t2
    ON t1.Task=t2.task

EDIT:-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

ここに画像の説明を入力

于 2013-10-16T02:50:37.753 に答える
0

あなたの正確な質問について詳しく知らなくても、おそらくこれでうまくいくでしょうか?

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);
于 2013-10-15T04:44:17.963 に答える