我有一个表,其中有许多列,其中约50列包含日期时间数据,这些数据表示用户执行过程时所采取的步骤
SELECT UserID, Intro_Req_DateTime, Intro_Onset_DateTime, Intro_Comp_DateTime, Info_Req_DateTime, Info_Onset_DateTime, Info_Comp_DateTime,
Start_Req_DateTime, Start_Onset_DateTime, Start_Comp_DateTime,
Check_Req_DateTime, Check_Onset_DateTime, Check_Comp_DateTime,
Validate_Req_DateTime, Validate_Onset_DateTime, Validate_Comp_DateTime,
....
FROM MyTable
我想找到用户在特定日期时间之后执行的步骤
示例我想查找用户ABC他在2019年5月2日17:25:36之后执行的第一步
我无法使用大小写检查代码,这需要花费很多时间
有更简单的方法吗?
P.S。谢谢大家提出的重新设计数据库的建议。.并非所有数据库都可以重新设计,该数据库适用于我们拥有的大型系统之一,并且已经使用了20多年。重新设计是不可行的。
答案 0 :(得分:3)
您可以使用CROSS APPLY
取消设置值。 UNPIVOT
的语法非常繁琐。
实际的查询文本应相当易于管理。无需复杂的CASE
语句。是的,您将必须在查询文本中显式列出所有50个列名,您不能避免,但是只会列出一次。
SELECT TOP(1)
A.StepName
,A.dt
FROM
MyTable
CROSS APPLY
(
VALUES
('Intro_Req', Intro_Req_DateTime)
,('Intro_Onset', Intro_Onset_DateTime)
,('Intro_Comp', Intro_Comp_DateTime)
.........
) AS A (StepName, dt)
WHERE
MyTable.UserID = 'ABC'
AND A.dt > '2019-05-02T17:25:36'
ORDER BY dt DESC;
另请参阅How to unpivot columns using CROSS APPLY in SQL Server 2012
答案 1 :(得分:1)
最好的方法是使用操作类型和完成操作的日期时间来设计表。然后,您可以使用简单的where子句查找所需内容。该表应类似于下表:
ID ActionType ActionDatetime
----------- ----------- -------------------
1492 1 2019-05-13 10:10:10
1494 2 2019-05-13 11:10:10
1496 3 2019-05-13 12:10:10
1498 4 2019-05-13 13:10:10
1500 5 2019-05-13 14:10:10
但是在当前解决方案中,您应该使用UNPIVOT来获得所需的东西。您可以在此LINK中找到更多信息。