简体   繁体   English

TSQL:如果记录为空,如何从查询结果中删除最后一条记录

[英]TSQL: how to delete last record from query result if record is NULL

Background: I am using a stored procedure below to retrieve hourly time series data. 背景:我正在使用下面的存储过程来检索每小时的时间序列数据。

SELECT *
   FROM (
      SELECT CAST(LocalDateTime as SmallDateTime) as [DateTime], DataValue, VariableID
         FROM DataValues
         WHERE SiteID = 2 and VariableID IN(1,3,30)
         ) TableDate
   PIVOT (SUM(DataValue) FOR VariableID IN ([1],[3],[30]))
   PivotTable ORDER BY [DateTime]

Usually the data is written to the database at the top of the hour, and the stored procedure is executed at 5 minutes past the hour to retrieve all existing values. 通常,数据会在每小时的最高时间写入数据库,并且存储过程会在每小时的5分钟后执行以检索所有现有值。

The problem is that occasionally the data retrieval on top of the hour fails for one of many sites and thus no new data is written to the DataValues table for that site. 问题在于,对于许多站点之一,有时每小时的数据检索都会失败,因此不会有新数据写入该站点的DataValues表。 However, the most recent hour is still present in the DataValues table because other sites wrote values to it. 但是,由于其他站点向其写入了值,因此DataValues表中仍存在最近的小时。 This results in a query result that has a record for the most recent hour but all fields are NULL . 这将导致查询结果具有最近一小时的记录,但所有字段均为NULL The code that handles the query results can deal with hourly data that is NULL for whatever reason except in cases where the very last record is NULL for all fields. 处理查询结果的代码无论出于何种原因都可以处理每小时为NULL数据,除非最后一条记录的所有字段均为NULL

Question: Is there a simple way to remove the last record of a query result (once pivoted per procedure above) if all fields of that record are NULL ? 问题:如果该记录的所有字段均为NULL ,是否有一种简单的方法来删除查询结果的最后一条记录(一次按上述过程操作)?

You can do this with by using row_number() : 您可以使用row_number()来做到这一点:

with cte as (
      SELECT *
      FROM (SELECT CAST(LocalDateTime as SmallDateTime) as [DateTime], DataValue, VariableID
            FROM DataValues
            WHERE SiteID = 2 and VariableID IN(1,3,30)
           ) TableDate
      PIVOT (SUM(DataValue) FOR VariableID IN ([1],[3],[30])) PivotTable
      ORDER BY [DateTime]
     )
select [DateTime], [1], [3], [30]
from (select cte.*, row_number() over (order by [DateTime] desc) as seqnum
      from cte
     ) t
where seqnum = 1 and [1] is null and [3] is null and [30] is null;

However, I think the easiest way is just to filter before the pivot : 但是,我认为最简单的方法是在pivot之前进行过滤:

      SELECT *
      FROM (SELECT CAST(LocalDateTime as SmallDateTime) as [DateTime], DataValue, VariableID
            FROM DataValues
            WHERE DataValue is not null
            WHERE SiteID = 2 and VariableID IN (1, 3, 30)
           ) TableDate
      PIVOT (SUM(DataValue) FOR VariableID IN ([1],[3],[30])) PivotTable
      ORDER BY [DateTime]

This has the potential disadvantage of removing other rows with NULL s in them. 这具有删除其他行中带有NULL的潜在缺点。 If that is a problem, the first method works better. 如果存在问题,则第一种方法效果更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM