试图创建一个日期字段来合并两个表
Trying to create a date field to union two tables
我正在尝试将两个数据库放在一个视图中,该视图将显示来自两个系统的发票。
一个 table 按日期列出发票(即 1 月份的销售额是带有 1 月份日期的任何发票),另一个 table 按年份和期间列出发票(因此,1 月份的销售额是“2017”期间 '7' - 与日期无关)。由于第二个系统允许在该期间日期范围之外的期间内过帐发票,我正在尝试使用案例语句从 year/period 字段创建一个日期字段,以显示相同的 Invoiced sales正如系统所做的那样。
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。联合中另一个 table 中的 InvDate 是 'datetime' 格式。
如何让 case 语句的输出成为日期时间格式?
我相信你只需要一个cast
:
select (cast(LedgerYear as varchar(255)) +
case . . .
) as InvDate
备注:
+
运算符适用于字符串和数字。当任何参数是数字时,它是加法。因此需要 cast()
/convert()
.
- 仅对字符串和日期常量使用单引号。不要将它们用于列名。
在 SQL 服务器中,您可以将其添加为计算列,这样您只需计算一次:
alter table t 添加 invDate as (cast(Ledgeryear as varchar(255)) + case . . . );
然后,该列在 table 中可用。
如果您使用的是 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
进行隐式转换
除了建议 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 的回答进行简化:
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
or 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 relies on the presence of .the .NET Framework Common Language Runtime (CLR).
我正在尝试将两个数据库放在一个视图中,该视图将显示来自两个系统的发票。
一个 table 按日期列出发票(即 1 月份的销售额是带有 1 月份日期的任何发票),另一个 table 按年份和期间列出发票(因此,1 月份的销售额是“2017”期间 '7' - 与日期无关)。由于第二个系统允许在该期间日期范围之外的期间内过帐发票,我正在尝试使用案例语句从 year/period 字段创建一个日期字段,以显示相同的 Invoiced sales正如系统所做的那样。
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。联合中另一个 table 中的 InvDate 是 'datetime' 格式。
如何让 case 语句的输出成为日期时间格式?
我相信你只需要一个cast
:
select (cast(LedgerYear as varchar(255)) +
case . . .
) as InvDate
备注:
+
运算符适用于字符串和数字。当任何参数是数字时,它是加法。因此需要cast()
/convert()
.- 仅对字符串和日期常量使用单引号。不要将它们用于列名。
在 SQL 服务器中,您可以将其添加为计算列,这样您只需计算一次:
alter table t 添加 invDate as (cast(Ledgeryear as varchar(255)) + case . . . );
然后,该列在 table 中可用。
如果您使用的是 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
进行隐式转换
除了建议 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 的回答进行简化:
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
or 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 relies on the presence of .the .NET Framework Common Language Runtime (CLR).