在 SQL 服务器的 WHERE 子句中使用 DATETIME
Using DATETIME in WHERE clause in SQL Server
我有这个问题
SELECT
[MsgNumber], [StateAfter],
DATETIMEFROMPARTS (SUBSTRING([TimeString], 7, 4),
SUBSTRING([TimeString], 4, 2),
SUBSTRING([TimeString], 1, 2),
SUBSTRING([TimeString], 12, 2),
SUBSTRING([TimeString], 15, 2),
SUBSTRING([TimeString], 18, 2), 0) AS dt
FROM
TABLE
WHERE
[MsgNumber] IN (5, 9, 13, 17)
ORDER BY
dt ASC, StateAfter ASC
输出(正常):
+-----------+-----------+-------------------------+
| MsgNumber | tateAfter | dt |
+-----------+-----------+-------------------------+
| 9 | 1 | 2018-03-09 17:22:00.000 |
| 9 | 0 | 2018-03-09 17:23:37.000 |
| 17 | 1 | 2018-03-09 17:23:37.000 |
| 17 | 1 | 2018-03-09 17:29:43.000 |
| 17 | 1 | 2018-03-09 17:36:21.000 |
+-----------+-----------+-------------------------+
我想在日期上添加一个条件;为避免内部日期时间编码错误,我使用 DATETIMEFROMPARTS 函数
SELECT [MsgNumber],[StateAfter]
,DATETIMEFROMPARTS ( SUBSTRING ( [TimeString] ,7 , 4 ), SUBSTRING ( [TimeString] ,4 , 2 ), SUBSTRING ( [TimeString] ,1 , 2 ),
SUBSTRING ( [TimeString] ,12 , 2 ), SUBSTRING ( [TimeString] ,15 , 2 ), SUBSTRING ( [TimeString] ,18 , 2 ) , 0) as dt
FROM TABLE
WHERE [MsgNumber] IN (5,9,13,17) AND (dt > DATETIMEFROMPARTS(2018,4,9,0,0,0,0) and dt < DATETIMEFROMPARTS(2018,5,9,0,0,0,0))
ORDER BY dt ASC,StateAfter ASC
错误:-
Messaggio 207, livello 16, stato 1, riga 5
Invalid column name 'dt'.
Messaggio 207, livello 16, stato 1, riga 5
Invalid column name 'dt'.
有人可以帮我理解为什么它不起作用吗?我也尝试了 BETWEEN 子句;谢谢
您不能在 where
子句中引用列别名。典型的解决方案是使用子查询或 CTE。但是 SQL 服务器有另一种我喜欢的方法,apply
:
SELECT [MsgNumber], [StateAfter], v.dt
FROM TABLE t CROSS APPLY
(VALUES (DATETIMEFROMPARTS(SUBSTRING ([TimeString], 7, 4), SUBSTRING([TimeString], 4, 2), SUBSTRING([TimeString], 1, 2),
SUBSTRING([TimeString], 12, 2), SUBSTRING( [TimeString], 15, 2), SUBSTRING([TimeString], 18, 2), 0)
)
) V(dt)
WHERE [MsgNumber] IN (5, 9, 13, 17) AND
v.dt > DATETIMEFROMPARTS(2018, 4, 9, 0, 0, 0, 0) AND
v.dt < DATETIMEFROMPARTS(2018, 5, 9, 0, 0, 0, 0))
ORDER BY dt ASC,StateAfter ASC;
我很好奇你不使用更简单的:
WHERE [MsgNumber] IN (5, 9, 13, 17) AND
v.dt > '20180409' AND
v.dt < '20180509'
(我没有使用连字符,因为无论国际化设置如何,此格式将始终被解释为 YYYYMMDD。)
别名 dt
不能在 WHERE
子句中使用。使用像这样的子查询:
SELECT t.[MsgNumber]
,t.[StateAfter]
,t.dt
FROM (
SELECT [MsgNumber]
,[StateAfter]
,DATETIMEFROMPARTS(SUBSTRING([TimeString], 7, 4), SUBSTRING([TimeString], 4, 2), SUBSTRING([TimeString], 1, 2), SUBSTRING([TimeString], 12, 2), SUBSTRING([TimeString], 15, 2), SUBSTRING([TimeString], 18, 2), 0) AS dt
FROM TABLE
) t
WHERE [MsgNumber] IN (
5
,9
,13
,17
)
AND (
dt > DATETIMEFROMPARTS(2018, 4, 9, 0, 0, 0, 0)
AND dt < DATETIMEFROMPARTS(2018, 5, 9, 0, 0, 0, 0)
)
ORDER BY dt ASC
,StateAfter ASC
您收到此错误是因为在您的 Table 中没有这样的列 dt。 dt 只是您在 select 中提供的别名,因此它不是列。所以你可以使用以下任何一种方法:
使用 CTE 或 SubQuery(推荐)
; with CTE
AS
(
SELECT [MsgNumber],[StateAfter]
,DATETIMEFROMPARTS ( SUBSTRING ( [TimeString] ,7 , 4 ), SUBSTRING ( [TimeString] ,4 , 2 ), SUBSTRING ( [TimeString] ,1 , 2 ),
SUBSTRING ( [TimeString] ,12 , 2 ),
SUBSTRING ( [TimeString] ,15 , 2 ), SUBSTRING ( [TimeString] ,18 , 2 ) , 0) as dt
FROM TABLE
)
SELECT
*
FROM CTE
WHERE [MsgNumber] IN (5,9,13,17)
AND
(
dt > DATETIMEFROMPARTS(2018,4,9,0,0,0,0) and dt < DATETIMEFROMPARTS(2018,5,9,0,0,0,0))
ORDER BY dt ASC,StateAfter ASC
在Where条件中给出公式(不推荐)
SELECT [MsgNumber],[StateAfter]
,DATETIMEFROMPARTS ( SUBSTRING ( [TimeString] ,7 , 4 ), SUBSTRING ( [TimeString] ,4 , 2 ), SUBSTRING ( [TimeString] ,1 , 2 ),
SUBSTRING ( [TimeString] ,12 , 2 ), SUBSTRING ( [TimeString] ,15 , 2 ), SUBSTRING ( [TimeString] ,18 , 2 ) , 0) as dt
FROM [TABLE]
WHERE [MsgNumber] IN (5,9,13,17) AND
(
DATETIMEFROMPARTS ( SUBSTRING ( [TimeString] ,7 , 4 ), SUBSTRING ( [TimeString] ,4 , 2 ), SUBSTRING ( [TimeString] ,1 , 2 ),
SUBSTRING ( [TimeString] ,12 , 2 ), SUBSTRING ( [TimeString] ,15 , 2 ), SUBSTRING ( [TimeString] ,18 , 2 ) , 0)
> DATETIMEFROMPARTS(2018,4,9,0,0,0,0)
and
DATETIMEFROMPARTS ( SUBSTRING ( [TimeString] ,7 , 4 ), SUBSTRING ( [TimeString] ,4 , 2 ), SUBSTRING ( [TimeString] ,1 , 2 ),
SUBSTRING ( [TimeString] ,12 , 2 ), SUBSTRING ( [TimeString] ,15 , 2 ), SUBSTRING ( [TimeString] ,18 , 2 ) , 0)
< DATETIMEFROMPARTS(2018,5,9,0,0,0,0))
ORDER BY dt ASC,StateAfter ASC
发生此错误是因为 dt 不是物理列。
您可以实现如下查询:
SELECT tbl.* FROM ( SELECT
[MsgNumber], [StateAfter],
DATETIMEFROMPARTS (SUBSTRING([TimeString], 7, 4),
SUBSTRING([TimeString], 4, 2),
SUBSTRING([TimeString], 1, 2),
SUBSTRING([TimeString], 12, 2),
SUBSTRING([TimeString], 15, 2),
SUBSTRING([TimeString], 18, 2), 0) AS dt
FROM
TABLE ) tbl
WHERE tbl.[MsgNumber] IN (5,9,13,17)
AND (tbl.dt > DATETIMEFROMPARTS(2018,4,9,0,0,0,0) AND tbl.dt < DATETIMEFROMPARTS(2018,5,9,0,0,0,0))
ORDER BY
tbl.dt ASC, tbl.StateAfter ASC
我有这个问题
SELECT
[MsgNumber], [StateAfter],
DATETIMEFROMPARTS (SUBSTRING([TimeString], 7, 4),
SUBSTRING([TimeString], 4, 2),
SUBSTRING([TimeString], 1, 2),
SUBSTRING([TimeString], 12, 2),
SUBSTRING([TimeString], 15, 2),
SUBSTRING([TimeString], 18, 2), 0) AS dt
FROM
TABLE
WHERE
[MsgNumber] IN (5, 9, 13, 17)
ORDER BY
dt ASC, StateAfter ASC
输出(正常):
+-----------+-----------+-------------------------+
| MsgNumber | tateAfter | dt |
+-----------+-----------+-------------------------+
| 9 | 1 | 2018-03-09 17:22:00.000 |
| 9 | 0 | 2018-03-09 17:23:37.000 |
| 17 | 1 | 2018-03-09 17:23:37.000 |
| 17 | 1 | 2018-03-09 17:29:43.000 |
| 17 | 1 | 2018-03-09 17:36:21.000 |
+-----------+-----------+-------------------------+
我想在日期上添加一个条件;为避免内部日期时间编码错误,我使用 DATETIMEFROMPARTS 函数
SELECT [MsgNumber],[StateAfter]
,DATETIMEFROMPARTS ( SUBSTRING ( [TimeString] ,7 , 4 ), SUBSTRING ( [TimeString] ,4 , 2 ), SUBSTRING ( [TimeString] ,1 , 2 ),
SUBSTRING ( [TimeString] ,12 , 2 ), SUBSTRING ( [TimeString] ,15 , 2 ), SUBSTRING ( [TimeString] ,18 , 2 ) , 0) as dt
FROM TABLE
WHERE [MsgNumber] IN (5,9,13,17) AND (dt > DATETIMEFROMPARTS(2018,4,9,0,0,0,0) and dt < DATETIMEFROMPARTS(2018,5,9,0,0,0,0))
ORDER BY dt ASC,StateAfter ASC
错误:-
Messaggio 207, livello 16, stato 1, riga 5
Invalid column name 'dt'.
Messaggio 207, livello 16, stato 1, riga 5
Invalid column name 'dt'.
有人可以帮我理解为什么它不起作用吗?我也尝试了 BETWEEN 子句;谢谢
您不能在 where
子句中引用列别名。典型的解决方案是使用子查询或 CTE。但是 SQL 服务器有另一种我喜欢的方法,apply
:
SELECT [MsgNumber], [StateAfter], v.dt
FROM TABLE t CROSS APPLY
(VALUES (DATETIMEFROMPARTS(SUBSTRING ([TimeString], 7, 4), SUBSTRING([TimeString], 4, 2), SUBSTRING([TimeString], 1, 2),
SUBSTRING([TimeString], 12, 2), SUBSTRING( [TimeString], 15, 2), SUBSTRING([TimeString], 18, 2), 0)
)
) V(dt)
WHERE [MsgNumber] IN (5, 9, 13, 17) AND
v.dt > DATETIMEFROMPARTS(2018, 4, 9, 0, 0, 0, 0) AND
v.dt < DATETIMEFROMPARTS(2018, 5, 9, 0, 0, 0, 0))
ORDER BY dt ASC,StateAfter ASC;
我很好奇你不使用更简单的:
WHERE [MsgNumber] IN (5, 9, 13, 17) AND
v.dt > '20180409' AND
v.dt < '20180509'
(我没有使用连字符,因为无论国际化设置如何,此格式将始终被解释为 YYYYMMDD。)
别名 dt
不能在 WHERE
子句中使用。使用像这样的子查询:
SELECT t.[MsgNumber]
,t.[StateAfter]
,t.dt
FROM (
SELECT [MsgNumber]
,[StateAfter]
,DATETIMEFROMPARTS(SUBSTRING([TimeString], 7, 4), SUBSTRING([TimeString], 4, 2), SUBSTRING([TimeString], 1, 2), SUBSTRING([TimeString], 12, 2), SUBSTRING([TimeString], 15, 2), SUBSTRING([TimeString], 18, 2), 0) AS dt
FROM TABLE
) t
WHERE [MsgNumber] IN (
5
,9
,13
,17
)
AND (
dt > DATETIMEFROMPARTS(2018, 4, 9, 0, 0, 0, 0)
AND dt < DATETIMEFROMPARTS(2018, 5, 9, 0, 0, 0, 0)
)
ORDER BY dt ASC
,StateAfter ASC
您收到此错误是因为在您的 Table 中没有这样的列 dt。 dt 只是您在 select 中提供的别名,因此它不是列。所以你可以使用以下任何一种方法:
使用 CTE 或 SubQuery(推荐)
; with CTE
AS
(
SELECT [MsgNumber],[StateAfter]
,DATETIMEFROMPARTS ( SUBSTRING ( [TimeString] ,7 , 4 ), SUBSTRING ( [TimeString] ,4 , 2 ), SUBSTRING ( [TimeString] ,1 , 2 ),
SUBSTRING ( [TimeString] ,12 , 2 ),
SUBSTRING ( [TimeString] ,15 , 2 ), SUBSTRING ( [TimeString] ,18 , 2 ) , 0) as dt
FROM TABLE
)
SELECT
*
FROM CTE
WHERE [MsgNumber] IN (5,9,13,17)
AND
(
dt > DATETIMEFROMPARTS(2018,4,9,0,0,0,0) and dt < DATETIMEFROMPARTS(2018,5,9,0,0,0,0))
ORDER BY dt ASC,StateAfter ASC
在Where条件中给出公式(不推荐)
SELECT [MsgNumber],[StateAfter]
,DATETIMEFROMPARTS ( SUBSTRING ( [TimeString] ,7 , 4 ), SUBSTRING ( [TimeString] ,4 , 2 ), SUBSTRING ( [TimeString] ,1 , 2 ),
SUBSTRING ( [TimeString] ,12 , 2 ), SUBSTRING ( [TimeString] ,15 , 2 ), SUBSTRING ( [TimeString] ,18 , 2 ) , 0) as dt
FROM [TABLE]
WHERE [MsgNumber] IN (5,9,13,17) AND
(
DATETIMEFROMPARTS ( SUBSTRING ( [TimeString] ,7 , 4 ), SUBSTRING ( [TimeString] ,4 , 2 ), SUBSTRING ( [TimeString] ,1 , 2 ),
SUBSTRING ( [TimeString] ,12 , 2 ), SUBSTRING ( [TimeString] ,15 , 2 ), SUBSTRING ( [TimeString] ,18 , 2 ) , 0)
> DATETIMEFROMPARTS(2018,4,9,0,0,0,0)
and
DATETIMEFROMPARTS ( SUBSTRING ( [TimeString] ,7 , 4 ), SUBSTRING ( [TimeString] ,4 , 2 ), SUBSTRING ( [TimeString] ,1 , 2 ),
SUBSTRING ( [TimeString] ,12 , 2 ), SUBSTRING ( [TimeString] ,15 , 2 ), SUBSTRING ( [TimeString] ,18 , 2 ) , 0)
< DATETIMEFROMPARTS(2018,5,9,0,0,0,0))
ORDER BY dt ASC,StateAfter ASC
发生此错误是因为 dt 不是物理列。
您可以实现如下查询:
SELECT tbl.* FROM ( SELECT
[MsgNumber], [StateAfter],
DATETIMEFROMPARTS (SUBSTRING([TimeString], 7, 4),
SUBSTRING([TimeString], 4, 2),
SUBSTRING([TimeString], 1, 2),
SUBSTRING([TimeString], 12, 2),
SUBSTRING([TimeString], 15, 2),
SUBSTRING([TimeString], 18, 2), 0) AS dt
FROM
TABLE ) tbl
WHERE tbl.[MsgNumber] IN (5,9,13,17)
AND (tbl.dt > DATETIMEFROMPARTS(2018,4,9,0,0,0,0) AND tbl.dt < DATETIMEFROMPARTS(2018,5,9,0,0,0,0))
ORDER BY
tbl.dt ASC, tbl.StateAfter ASC