Обновление таблицы на основе глобального совпадения подстроки с помощью оператора IF или CASE - PullRequest
3 голосов
/ 11 января 2012

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

Mon Nov 14 14:52:46 PST 2011
Fri Nov 04 07:50:21 PDT 2011
Thu Dec 01 00:00:00 PST 2011

Есть три месяца: ноябрь, декабрь, январь. Я хочу сохранить новый формат даты в новых столбцахв этом формате:

11-14-2011, 11-04-2011, 12-01-2011 и т. д ....

Я могусделать это с помощью оператора update, который соответствует названию месяца подстроки и заменяет его соответствующим числовым значением.Так что я могу сделать это примерно так:

UPDATE tabel 
   set col1 = REPLACE(substring(col2, 5,3) 'Nov', 11)

И это работает в течение первого месяца, когда я бегу.Но когда я затем добавляю Dec и Jan, он работает только для тех месяцев и сбрасывает строку для трехбуквенных месяцев во всех остальных строках, которые я только что сделал.

Я не знаю, как выполнить это ОБНОВЛЕНИЕи правильно ЗАМЕНИТЕ команду, чтобы она соответствовала всем трем месяцам в базе данных, а затем записывает новый формат в новый столбец, как я хочу.Я немного новичок в T-SQL, и до сих пор я поражен количеством документации там.Я попытался поместить все три месяца в ряд утверждений ОБНОВЛЕНИЯ, и это не сработало.Я думаю, что нужно идти строка за строкой, проверять условие и затем выполнять обновление, если оно совпадает.

Может быть так:

IF @dateColSubString = 'Jan' Then
   UPDATE table
         set newDateCol = REPLACE(substring(col2, 5,3) 'Jan', 01) + '-2012'
   COMMIT
IF @dateColSubString = 'Dec' Then
   UPDATE table
         set newDateCol = REPLACE(substring(col2, 5,3) 'Dec', 12) + '-2011'
   COMMIT

, чтобы сделать такие значения в новом столбце '01 -2011 ', а затем не сбрасывать их до старых значений при запуске того же обновлениязапросите «Nov», а затем «Dec», чтобы изменить эти строки.

Надеюсь, это имеет смысл.

Ответы [ 2 ]

3 голосов
/ 11 января 2012

Попробуйте и сделайте все, что вы хотите с вашей датой и временем

DECLARE @t TABLE(str varchar(100))
INSERT @t
VALUES('Mon Nov 14 14:52:46 PST 2011'),('Fri Nov 04 07:50:21 PDT 2011'),('Thu Dec 01 00:00:00 PST 2011')

SELECT 
    CAST(DATEPART(MONTH, CAST(SUBSTRING(str, 5, 6) +' '+RIGHT(str, 4) AS DATETIME)) AS VARCHAR) +'-'+ RIGHT(str, 4),
    CAST(SUBSTRING(str, 5, 6) +' '+RIGHT(str, 4) AS DATETIME),
    CONVERT(VARCHAR, CAST(SUBSTRING(str, 5, 6) +' '+RIGHT(str, 4) AS DATETIME), 110)
FROM @t

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

SELECT 
    CAST(DATEPART(MONTH, CAST(SUBSTRING(order_send, 5, 6) +' '+RIGHT(order_send, 4) AS DATETIME)) AS VARCHAR) +'-'+ RIGHT(order_send, 4),
    CAST(SUBSTRING(order_send, 5, 6) +' '+RIGHT(order_send, 4) AS DATETIME),
    CONVERT(VARCHAR, CAST(SUBSTRING(order_send, 5, 6) +' '+RIGHT(order_send, 4) AS DATETIME), 110)
FROM YourTableName
2 голосов
/ 12 января 2012

Если вы можете потерять информацию о часовом поясе, вы можете просто удалить день недели и части часового пояса и преобразовать полученную строку в datetime, используя простые CAST или CONVERT, например:

;
WITH StringDates (OldDateCol) AS (
  SELECT 'Mon Nov 14 14:52:46 PST 2011' UNION ALL
  SELECT 'Fri Nov 04 07:50:21 PDT 2011' UNION ALL
  SELECT 'Thu Dec 01 00:00:00 PST 2011'
)
SELECT
  OldDateCol,
  NewDateCol = CAST(SUBSTRING(STUFF(OldDateCol, 21, 4, ''), 5, 99) AS datetime)
FROM StringDates

то есть STUFF удаляет часть часового пояса, а SUBSTRING пропускает день недели.

Вот набор результатов:

OldDateCol                    NewDateCol
----------------------------  -----------------------
Mon Nov 14 14:52:46 PST 2011  2011-11-14 14:52:46.000
Fri Nov 04 07:50:21 PDT 2011  2011-11-04 07:50:21.000
Thu Dec 01 00:00:00 PST 2011  2011-12-01 00:00:00.000

С другой стороны, если вы (или, возможно, в конечном итоге) используете столбец datetimeoffset для хранения преобразованных значений и хотите сохранить бит информации о часовом поясе, вы можете попробовать следующий метод:

;
WITH StringDates (OldDateCol) AS (
  SELECT 'Mon Nov 14 14:52:46 PST 2011' UNION ALL
  SELECT 'Fri Nov 04 07:50:21 PDT 2011' UNION ALL
  SELECT 'Thu Dec 01 00:00:00 PST 2011'
),
DatesAndTimeZones AS (
  SELECT
    OldDateCol,
    NewDateCol = CAST(SUBSTRING(STUFF(OldDateCol, 21, 4, ''), 5, 99) AS datetime),
    TimeZoneName = SUBSTRING(OldDateCol, 21, 4)
  FROM StringDates
),
TimeZones (Name, Offset) AS (
  SELECT 'PST', '-08:00' UNION ALL
  SELECT 'PDT', '-07:00'
)
SELECT
  d.OldDateCol,
  NewDateTimeOffsetCol = TODATETIMEOFFSET(d.NewDateCol, t.Offset)
FROM DatesAndTimeZones d
  INNER JOIN TimeZones t ON d.TimeZoneName = t.Name

Здесь преобразование выполняется в два этапа.

Первый шаг преобразует строки в значения datetime, как и раньше, а также извлекает из них имена часовых поясов.

По сути, этих двух значений будет достаточно для преобразования datetime в datetimeoffset, но SQL Server не распознает часовой пояс имен , он может понимать только смещения , в виде +hh:mm или -hh:mm. Таким образом, вам необходимо заменить имена соответствующими смещениями, что можно сделать с помощью справочной таблицы (TimeZones CTE выше играет свою роль).

Итак, следующий (и последний) шаг - присоединение к справочной таблице и вызов функции TODATETIMEOFFSET() для получения окончательных результатов.

Вот результаты второго запроса:

OldDateCol                    NewDateTimeOffsetCol
----------------------------  ----------------------------------
Mon Nov 14 14:52:46 PST 2011  2011-11-14 14:52:46.000 -08:00
Fri Nov 04 07:50:21 PDT 2011  2011-11-04 07:50:21.000 -07:00
Thu Dec 01 00:00:00 PST 2011  2011-12-01 00:00:00.000 -08:00

Ссылки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...