从50列中选择

时间:2019-05-13 04:20:00

标签: sql sql-server

我有一个表,其中有许多列,其中约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多年。重新设计是不可行的。

2 个答案:

答案 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中找到更多信息。