2017-01-06 1 views
1

Я пытаюсь собрать две базы данных в представлении, которое будет отображать выставление счетов из обеих систем.Попытка создать поле даты для объединения двух таблиц

В одной таблице перечислены счета-фактуры по дате (то есть продажи в январе - это любой счет-фактура с январской датой), в другой таблице перечислены счета-фактуры по годам и периодам (так что продажи января - период «2017» - независимо от даты) , Поскольку вторая система позволяет публиковать счета-фактуры в течение периода, который находится за пределами этого диапазона дат периодов, я пытаюсь создать поле даты из полей года/периода с помощью case-case, чтобы показать тот же объем выставленных счетов, что и система делает.

LedgerYear + 
case 
when LedgerPeriod = 4 then '-10-01' 
when LedgerPeriod = 5 then '-11-01' 
when LedgerPeriod = 6 then '-12-01' 
when LedgerPeriod = 7 then '-01-01' 
when LedgerPeriod = 8 then '-02-01' 
when LedgerPeriod = 9 then '-03-01' 
when LedgerPeriod = 10 then '-04-01' 
when LedgerPeriod = 11 then '-05-01' 
when LedgerPeriod = 12 then '-06-01' 
when LedgerPeriod = 1 then '-07-01' 
when LedgerPeriod = 2 then '-08-01' 
when LedgerPeriod = 3 then '-09-01' 
end 
as 'InvDate', 

Я получаю следующее сообщение ..

Error converting data type varchar to numeric. 

Предположительно, LedgerYear числовой и '-10-01' и т.д., VARCHARS. InvDate в другой таблице в объединении находится в формате «datetime».

Как я могу получить вывод оператора case в формате даты и времени?

+0

Данные примера и желаемые результаты действительно полезны для объяснения проблемы. –

+0

попробуйте выбрать CAST (CAST (ledgeryear as float) как int) – Chanukya

+0

, какую версию SQL-сервера вы используете? –

ответ

3

Я считаю, что вам просто нужно cast:

select (cast(LedgerYear as varchar(255)) + 
     case . . . 
     ) as InvDate 

Примечания:

  • Оператор + работает на обеих строк и чисел. Когда любой аргумент является числом, это дополнение. Следовательно, необходимо наличие cast()/convert().
  • Используйте только одинарные кавычки для констант строк и дат. Не используйте их для имен столбцов.
  • В SQL Server, вы можете добавить это в качестве вычисляемого столбца, так что вы только должны сделать расчет один раз:

    альтер таблица т добавить invDate, как (литая (Ledgeryear, как VARCHAR (255)) + случай.. .);

Затем колонка доступна в таблице.

+0

Это исправлено - Спасибо! – dazzathedrummer

+0

Возможно, вы захотите также преобразовать его в формат даты после присоединения к значениям –

0

Если вы используете SQL сервер 2012+, то вы можете использовать использовать CONCAT и Choose функцию

select concat(LedgerYear , choose(LedgerPeriod,'-07-01', 
               '-08-01', 
               '-09-01', 
               '-10-01', 
               '-11-01', 
               '-12-01', 
               '-01-01', 
               '-02-01', 
               '-03-01', 
               '-04-01', 
               '-05-01', 
               '-06-01')) as 'InvDate' 

CONCAT делает неявное преобразование

+0

Я никогда не сталкивался с «ВЫБЕРИТЕ» раньше, полезно знать, спасибо! – 3N1GM4

2

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

SELECT 
    CONCAT(LedgerYear, 
      CASE LedgerPeriod 
       WHEN 1 THEN '-07-01' 
       WHEN 2 THEN '-08-01' 
       WHEN 3 THEN '-09-01' 
       WHEN 4 THEN '-10-01' 
       WHEN 5 THEN '-11-01' 
       WHEN 6 THEN '-12-01' 
       WHEN 7 THEN '-01-01' 
       WHEN 8 THEN '-02-01' 
       WHEN 9 THEN '-03-01' 
       WHEN 10 THEN '-04-01' 
       WHEN 11 THEN '-05-01' 
       WHEN 12 THEN '-06-01' 
      END 
     ) AS InvDate, 
FROM someTable 

Я включил свой CASE заявление от searched CASE к simple CASE заявление, чтобы удалить некоторые повторения, можно в равной степени использовать CHOOSE для дальнейшего упрощения в соответствии с Prdp «s ответ:

SELECT 
    CONCAT(LedgerYear, 
      CHOOSE(@LedgerPeriod, '-07-01', 
            '-08-01', 
            '-09-01', 
            '-10-01', 
            '-11-01', 
            '-12-01', 
            '-01-01', 
            '-02-01', 
            '-03-01', 
            '-04-01', 
            '-05-01', 
            '-06-01') 
     ) AS InvDate, 
FROM someTable 

Тем не менее, возможно, вы достигнете того, что вы пытаетесь сделать гораздо проще:

SELECT 
CAST(
    CAST(@LedgerYear AS VARCHAR(4)) + 
    RIGHT('0' + CAST(CASE WHEN @LedgerPeriod <= 6 
          THEN @LedgerPeriod + 6 
          ELSE (@LedgerPeriod + 6) % 12 
         END AS VARCHAR(2)), 2) + 
    '01' 
AS DATETIME) AS columnName 
FROM someTable 

(и есть, вероятно, еще более элегантный способ переложить свои номера периода в месяц номеров)

Это дает вам реальную DATETIME поле, которое вы можете выбрать, чтобы представить, как вам нравится с помощью CONVERT или FORMAT:

DECLARE @LedgerYear INT = 2016 
DECLARE @LedgerPeriod INT = 4 
DECLARE @LedgerDate DATETIME 

SELECT @LedgerDate = 
    CAST(
     CAST(@LedgerYear AS VARCHAR(4)) + 
     RIGHT('0' + CAST(CASE WHEN @LedgerPeriod <= 6 
           THEN @LedgerPeriod + 6 
           ELSE (@LedgerPeriod + 6) % 12 
          END AS VARCHAR(2)), 2) + 
     '01' 
    AS DATETIME) 

SELECT CONVERT(VARCHAR,@LedgerDate,101) -- U.S. (slashes) 
SELECT CONVERT(VARCHAR,@LedgerDate,110) -- USA (hyphens) 
SELECT CONVERT(VARCHAR,@LedgerDate,103) -- British/French (slashes) 

SELECT FORMAT(@LedgerDate, 'd', 'en-US') -- US English 
SELECT FORMAT(@LedgerDate, 'D', 'en-US') -- US English verbose 
SELECT FORMAT(@LedgerDate, 'd', 'en-GB') -- British English 
SELECT FORMAT(@LedgerDate, 'D', 'en-GB') -- British English verbose 

SELECT FORMAT(@LedgerDate, 'dd_|_MM_|_yyyy') -- Custom format 

Помните, что согласно MSDN:

FORMAT зависит от наличия .the .NET Framework Common Language Runtime (CLR).