Обновить столбцы из информации другой таблицы, используя переменные с возвратом нескольких строк - PullRequest
0 голосов
/ 06 января 2020

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

Для начала я использую SQL инструмент управления сервером 2018 для моей работы. У меня есть две таблицы X и Y, таблица X содержит идентификатор столбца, A, B, C ... и таблица Y содержит идентификатор столбца, Ax, Ay, Bx, By, Cx, Cy et c.

Мне нужно обновить таблицу X, столбец A = Ax + Ay, если Ax> Ay, или A = Ay + Ax, если Ax <= Ay, поэтому значение в столбце A будет AxAy или AyAx. </p>

То же со столбцом B C et c.

Я пытаюсь использовать функцию объявить, но она выдает сообщение об ошибке, в котором подзапрос возвратил более 1 значения, я понимаю, что это, вероятно, потому что запросы набора возвращают несколько строк данных Но как лучше это сделать?

declare @column varchar (20), @x varchar (20), @y varchar(20) 
set @column=(select A from TableX);
set @x=(select Ax from TableY) 
set @y=(select Ay from TableY) 
update TableX
set @column=(@y+@x)
from TableX 
inner join TableY
on TableX.ID=TableY.ID 
where @x <= @y

Пожалуйста, не могли бы вы помочь?

Большое спасибо заранее.

Ответы [ 3 ]

0 голосов
/ 06 января 2020
  1. Самый простой способ получить «Ax, затем Ay или Ay, затем Ax, в зависимости от того, что меньше», это использовать выражение CASE.
    CASE when @x < @y then @x + @y else @y + @x END

Вы не можете присвоить имя столбца переменной, а затем запустить SQL, который говорит ей обновить столбец, указанный в этой переменной. Это просто не поддерживается в SQL: вы должны ВСЕГДА знать, какие столбцы вы обновляете во время написания выписки. Ближайшим эквивалентом является использование Dynami c SQL, что почти всегда является плохой идеей.

Структура вашего кода показывает, что вы думаете «строка за строкой» - делайте это на строка, затем эта строка, затем следующая вещь в строке и, наконец, переход к следующей строке. Эффективность SQL достигается, когда вы думаете в наборах. У вас должен быть один SQL оператор, возможно, с CTE для определения индивидуальных результатов.

Пока я пытался написать SQL, который я бы порекомендовал, Максим Золотенко предоставил полный ответ. Я все еще публикую это, потому что думаю, что вопросы, которые я поднял, полезны для размышления.

0 голосов
/ 06 января 2020

Вы можете просто обновить каждый столбец в выражении вместо использования функции. Копирование и вставка могут сделать это действительно просто.

UPDATE dbo.X
SET x.A = CASE WHEN Ax > Ay THEN Ax+Ay ELSE Ay+Ax END,
x.B = CASE WHEN Bx > By THEN Bx+BY ELSE By+Bx END
FROM X
INNER JOIN Y
ON x.ID = Y.ID

Если вы хотите иметь возможность запускать это на разных столбцах с одинаковым шаблоном, не добавляя операторы SET в этот запрос на обновление, вам придется использовать динамический c sql, поскольку имена столбцов не могут быть переменными. Вот динам c sql.

DECLARE @columnPrefix VARCHAR(20) = 'A';

DECLARE @updateQuery VARCHAR(MAX) = 'UPDATE dbo.X  
SET x.' + @columnPrefix + '= CASE WHEN ' + @columnPrefix + 'x > ' + @columnPrefix + 'y THEN ' + @columnPrefix + 'x+' + @columnPrefix + 'y ELSE ' + @columnPrefix + 'y+' + @columnPrefix + 'x END
FROM X
INNER JOIN Y
ON x.ID = Y.ID';
EXEC(@updateQuery);```
0 голосов
/ 06 января 2020

Вы можете попробовать это:

update  TableX
set     TableX.A =  case when TableY.Ax <= TableY.Ay then TableY.Ax + TableY.Ay
                        else TableY.Ay + TableY.Ax
                    end,
        TableX.B = case when TableY.Bx <= TableY.By then TableY.Bx + TableY.By
                        else TableY.By + TableY.Bx
                    end,
        TableX.C = case when TableY.Cx <= TableY.Cy then TableY.Cx + TableY.Cy
                        else TableY.Cy + TableY.Cx
                    end
from    TableX 
inner join TableY on TableX.ID=TableY.ID 

В общем, внимательно прочитайте об операторе ОБНОВЛЕНИЕ и операторе CASE .

Обновлено , согласно @ Hong2020 комментариев:

Вы можете использовать Dynami c SQL для обновления столбцов в любых комбинациях. Например, это может быть хранимая процедура ( Обновлено снова в 2020 г. 9 января ):

create procedure dbo.SP_UPDATE_COLS
    @Column     nvarchar(100),  --  column to be updated
    @xCol       nvarchar(100),
    @yCol       nvarchar(100)
as

    declare @SQL    nvarchar(max) = '
    update  TableX
    set     TableX.' + @Column + ' =  case when TableY.' + @xCol + ' <= TableY.' + @yCol + ' then ''^''+TableY.' + @xCol + ' + ''^'' + TableY.' + @yCol + '
                            else ''^'' + TableY.' + @yCol + ' + ''^'' + TableY.' + @xCol + '
                        end
    from    TableX 
    inner join TableY on TableX.ID=TableY.ID
    ';

    exec(@SQL);
    --select    @SQL;
go
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...