在列SQL SERVER中获取总小时数

时间:2018-09-17 08:40:54

标签: sql sql-server calculated-columns hour

Sql Fiddle Example

我有这个结果表

// token is the string representation of the SAML1 token
// expectedCertThumb is the expected certificate's thumbprint
protected bool ValidateToken( string token, string expectedCertThumb, out string userName )
{
 userName = string.Empty;

 if (string.IsNullOrEmpty(token)) return false;

 var xd = new XmlDocument();
 xd.PreserveWhitespace = true;
 xd.LoadXml(token);

 XmlNamespaceManager mgr = new XmlNamespaceManager(xd.NameTable);
 mgr.AddNamespace("trust", "http://docs.oasis-open.org/ws-sx/ws-trust/200512");
 mgr.AddNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
 mgr.AddNamespace("saml", "urn:oasis:names:tc:SAML:1.0:assertion");

 // assertion
 XmlElement assertionNode = (XmlElement)xd.SelectSingleNode("//trust:RequestSecurityTokenResponseCollection/trust:RequestSecurityTokenResponse/trust:RequestedSecurityToken/saml:Assertion", mgr);

 // signature
 XmlElement signatureNode = (XmlElement)xd.GetElementsByTagName("Signature")[0];

 var signedXml = new SamlSignedXml( assertionNode );
 signedXml.LoadXml(signatureNode);

 X509Certificate2 certificate = null;
 foreach (KeyInfoClause clause in signedXml.KeyInfo)
 {
  if (clause is KeyInfoX509Data)
  {
   if (((KeyInfoX509Data)clause).Certificates.Count > 0)
   {
    certificate =
    (X509Certificate2)((KeyInfoX509Data)clause).Certificates[0];
   }
  }
 }

 // cert node missing
 if (certificate == null) return false;

 // check the signature and return the result.
 var signatureValidationResult = signedXml.CheckSignature(certificate, true);

 if (signatureValidationResult == false) return false;

 // validate cert thumb
 if ( !string.IsNullOrEmpty( expectedCertThumb ) )
 {
  if ( !string.Equals( expectedCertThumb, certificate.Thumbprint ) )
   return false;
 }

 // retrieve username

 // expires = 
 var expNode = xd.SelectSingleNode("//trust:RequestSecurityTokenResponseCollection/trust:RequestSecurityTokenResponse/trust:Lifetime/wsu:Expires", mgr );

 DateTime expireDate;

 if (!DateTime.TryParse(expNode.InnerText, out expireDate)) return false; // wrong date

 if (DateTime.UtcNow > expireDate) return false; // token too old

 // claims
 var claimNodes =                 
   xd.SelectNodes("//trust:RequestSecurityTokenResponseCollection/trust:RequestSecurityTokenResponse/trust:RequestedSecurityToken/"+
                  "saml:Assertion/saml:AttributeStatement/saml:Attribute", mgr );
 foreach ( XmlNode claimNode in claimNodes )
 {
  if ( claimNode.Attributes["AttributeName"] != null && 
              claimNode.Attributes["AttributeNamespace"] != null &&
       string.Equals( claimNode.Attributes["AttributeName"].Value, "name", StringComparison.InvariantCultureIgnoreCase ) &&   
                     string.Equals( claimNode.Attributes["AttributeNamespace"].Value, "http://schemas.xmlsoap.org/ws/2005/05/identity/claims", StringComparison.InvariantCultureIgnoreCase ) &&
         claimNode.ChildNodes.Count == 1 
      )
  {
   userName = claimNode.ChildNodes[0].InnerText;
   return true;
  }
 }

 return false;
}

我需要获取总计小时数,例如从09:00到18:00,总共有:

  

9

小时,我需要得到这个小时数

4 个答案:

答案 0 :(得分:2)

您的表架构hourvarchar,您需要将其转换为时间,然后进行计算

SELECT  datediff(hour,min(cast(hour as time)),max(cast(hour as time)))
FROM Timetable

sqlfiddle

注意

我建议您将hour列设为datetimetime而不是varchar。因为hour列的意图是时间。


编辑

如果您的时间为9:00 to 17:30,则可以尝试使用datediff分钟来获取总的比较分钟数,然后除以60来获取小时数。

SELECT datediff(minute,min(cast(hour as time)),max(cast(hour as time))) / CAST(60 as float)
FROM Timetable

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=6e005cdfad4eca3ff7c4c92ef14cc9c7

答案 1 :(得分:1)

使用datediff函数

select datediff(hour,min(h),max(h)) from
(

select CAST(hour AS TIME) as h from Timetable
  ) as  t

强烈不同意将时间值放入varchar中,因此最好将数据类型从varchar更改为time

答案 2 :(得分:1)

declare @a time = '13:00',@b time = '17:30'  --- Here you can give time, what you need.
select distinct convert(varchar(20)
, datediff(MINUTE,@a,@b) / 60) 
  + ':' + 
  convert(varchar(20), datediff(MINUTE,@a,@b) % 60) 
from #Timetable 
where hour in (@a,@b)

用于您的SQL Fiddle示例数据。

答案 3 :(得分:0)

很显然,您需要使用datediff()。但是,您应该在几分钟或几秒钟内完成datediff(),然后转换为小时:

SELECT datediff(minute, min(cast(hour as time)), max(cast(hour as time))) / 60.0
FROM Timetable;

这将处理小时数不是确切小时数的情况。