SQL-запрос для обновления столбца на основе значений других столбцов в той же таблице - PullRequest
5 голосов
/ 02 декабря 2011

Хорошо, это сложно выразить, так что вот так ...

Я использую MS SQL Server 2008 R2. У меня есть временная таблица, которая, скажем, имеет два уже заполненных столбца. Есть третий пустой столбец, который я хочу заполнить на основе значения первых двух столбцов. Что я хочу сделать, это создать guid (используя NEWUID ()) для каждой соответствующей комбинации из col1 и col2. Вот наглядный пример:

Допустим, у меня есть временная таблица, которая изначально выглядит так:

Name    Activity    SpecialId
James   Running     
James   Running
James   Walking
John    Running
John    Running
John    Walking

Я хочу, чтобы он обновлялся с новыми GUID, чтобы он выглядел так:

Name    Activity    SpecialId
James   Running     SOMEFAKEGUID_1
James   Running     SOMEFAKEGUID_1
James   Walking     SOMEFAKEGUID_2
John    Running     SOMEFAKEGUID_3
John    Running     SOMEFAKEGUID_3
John    Walking     SOMEFAKEGUID_4

Обратите внимание, как создается новый GUID для каждой подходящей пары. Таким образом, комбинация James / Running имеет одинаковый GUID для всех комбинаций James / Running ... и John / Running также имеет тот же GUID для комбинаций John / Running, но не тот же GUID, что и в комбинациях James / Running.

Я пытался сделать это как можно более ясным, но, надеюсь, это не так ясно, как грязь!

Может кто-нибудь показать мне, как будет выглядеть SQL-запрос, чтобы обновить временную таблицу с правильными идентификаторами GUID?

Заранее спасибо.

Ryan

Ответы [ 3 ]

3 голосов
/ 02 декабря 2011

Использование NEWID () кажется болезненным . Используя его, CTE создает отдельный идентификатор, поэтому вам нужна промежуточная таблица.

Declare @Table as table (name varchar(20), activity varchar(20) , SpecialID uniqueidentifier)
Declare @DistinctTable as table (name varchar(20), activity varchar(20) , SpecialID uniqueidentifier)

INSERT INTO @Table 
(name, activity)
values
('James','Running'),    
('James','Running'),
('James','Walking'),
('John','Running'),
('John','Running'),
('John','Walking')



WITH distinctt 
     AS (SELECT DISTINCT name, 
                         activity 
         FROM   @Table) 
INSERT INTO @DistinctTable 
SELECT name, 
       activity, 
       Newid() 
FROM   distinctt 

UPDATE @Table 
SET    specialid = dt.specialid 
FROM   @Table t 
       INNER JOIN @DistinctTable dt 
         ON t.activity = dt.activity 
            AND t.name = dt.name 

SELECT * FROM @Table 

Производит

name                 activity             SpecialID
-------------------- -------------------- ------------------------------------
James                Running              AAA22BC5-51FE-43B3-8CC9-4C4A5B4CC981
James                Running              AAA22BC5-51FE-43B3-8CC9-4C4A5B4CC981
James                Walking              1722B76B-5F17-4931-8D7C-2ECADB5A4DFD
John                 Running              FBC1F86B-592D-4D30-ACB3-80DA26B00900
John                 Running              FBC1F86B-592D-4D30-ACB3-80DA26B00900
John                 Walking              84282844-AAFD-45CA-9218-F7933E5102C6
0 голосов
/ 02 декабря 2011

Что ж, я знаю, что вы не используете mySQL, но вот как это будет работать в mySQL (протестировано)

MERGE INTO temp_table AS tt
  USING      (
    select newId() as spec_key, name, activity from (
    select distinct name, activity from temp_table) as anotherTemp 
      ON   anotherTemp.activity       = tt.activity
      and anotherTemp.name = tt.name
WHEN MATCHED
  THEN UPDATE
    SET        specialID = anotherTemp.spec_key;

Хотя производительность не будет хорошей.

0 голосов
/ 02 декабря 2011

Я уверен, что есть лучшие способы сделать это, но вы можете попробовать следующее:

WITH TableId AS
(
    SELECT DISTINCT Name, Activity
    FROM YourTable
)

UPDATE A
SET A.SpecialId = B.SpecialId
FROM YourTable A
INNER JOIN (SELECT Name, Activity, NEWID() SpecialId FROM TableId) B
ON A.Name = B.Name AND A.Activity = B.Activity
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...