How to most effectively get the first preceding/subsequent entry outside a given time interval?How do I...

What did Putin say about a US deep state in his state-of-the-nation speech; what has he said in the past?

put country dropdown in phtml file in magento2

Why do we divide Permutations to get to Combinations?

Could Comets or Meteors be used to Combat Global Warming?

Identical projects by students at two different colleges: still plagiarism?

Relation between roots and coefficients - manipulation of identities

Integral check. Is partial fractions the only way?

How to achieve physical gender equality?

Current measurement op-amp calculation

What dissuades people from lying about where they live in order to reduce state income taxes?

Is layered encryption more secure than long passwords?

Found a major flaw in paper from home university – to which I would like to return

Ramanujan's radical and how we define an infinite nested radical

Why don't reads from /dev/zero count as I/O?

Manager has noticed coworker's excessive breaks. Should I warn him?

Why does the Binomial Theorem use combinations and not permutations for its coefficients?

How to know if I am a 'Real Developer'

Does changing "sa" password require a SQL restart (in mixed mode)?

Microphone on Mars

Is opening a file faster than reading variable content?

Why didn't Lorentz conclude that no object can go faster than light?

How can a kingdom keep the secret of a missing monarch from the public?

Coworker is trying to get me to sign his petition to run for office. How to decline politely?

Does the kobold player race feature, Pack Tactics, give ranged attacks advantage?



How to most effectively get the first preceding/subsequent entry outside a given time interval?


How do I efficiently get “the most recent corresponding row”?How to join by most recent preceding date?Get the latest record and count them with time intervalFind the first datetime intervalThe fastest way to get the most recent recordsGroup daily schedule into [Start date; End date] intervals with the list of week daysCan SQL Server full-text search tokenize words within words?Given an arbitrary pair of origin & destination, how do I design a system that can effectively query all paths that cross the pair from a GPS dataset?CPU and memory utilization within the date and time givenAltering partition functions dynamically by utilizing triggers













1















We have a SQL Server DB that contains a large table (>100M rows) with archive values, basically in the form of [Id], [StationId], [DatapointId], [Timestamp], [Value]. As the stations do not get polled, there aren't any regular intervals at which a station sends a datapoint, so the timestamps are set to arbitrary times.



For our web visualization, I need to extract entries from this table for a pannable chart that I'm building with D3.js. I need to query by StationId, DatapointId, StartDate and EndDate. This is simple and works as expected, but for the line chart that it feeds, I do need additional data, namely the first value before the chosen time interval, and (if there is one) the first value after the interval. This is neccessary to draw the line from the left resp. right boundary of the chart to the first/last value within the interval (otherwise the data within the chart would look somewhat "isolated" because the line stops before the charts boundaries, like there's no data before or after the values in the chosen interval).



At the moment I need to run 3 queries: one to get the data within the interval, one to retrieve the first matching row before StartDate, and anotherone to get the first matching row after EndDate.



It works, and after creating a covering index the speed is ok, but I think there might be a way to reduce the number of roundtrips to the DB. Do you have any idea?










share|improve this question







New contributor




Robert is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    Hi, could you add the query you tried,your sql server version, and if possible the table definition + sample data?

    – Randi Vertongen
    4 hours ago











  • Do you notice any performance issues as a result of the three trips to the database? Unless it's causing an issue, your existing solution might be good enough. There are always windowing functions you can use (SQL Server 2012+) if you really want to reduce the number of trips, but basically you need to decide if it's worth the effort.

    – Randolph West
    3 hours ago











  • Please edit the question andd the query you use. It's not clear if you query for a single StationID, for a single (StationID, DatapointID) combination or for all stations in a specific time range.

    – ypercubeᵀᴹ
    3 hours ago











  • Thanks for your comments. I did not show my queries because I did not want to bias your answers, they are very basic select/select top where thingies anyway. I need to query for a single StationId and a single DatapointId at a time.

    – Robert
    3 hours ago











  • @RandolphWest: The performance is ok, but the chance of reducing the execution time by 2/3 is very tempting. Thanks for mentioning windowing functions, I'll have a look at that!

    – Robert
    3 hours ago
















1















We have a SQL Server DB that contains a large table (>100M rows) with archive values, basically in the form of [Id], [StationId], [DatapointId], [Timestamp], [Value]. As the stations do not get polled, there aren't any regular intervals at which a station sends a datapoint, so the timestamps are set to arbitrary times.



For our web visualization, I need to extract entries from this table for a pannable chart that I'm building with D3.js. I need to query by StationId, DatapointId, StartDate and EndDate. This is simple and works as expected, but for the line chart that it feeds, I do need additional data, namely the first value before the chosen time interval, and (if there is one) the first value after the interval. This is neccessary to draw the line from the left resp. right boundary of the chart to the first/last value within the interval (otherwise the data within the chart would look somewhat "isolated" because the line stops before the charts boundaries, like there's no data before or after the values in the chosen interval).



At the moment I need to run 3 queries: one to get the data within the interval, one to retrieve the first matching row before StartDate, and anotherone to get the first matching row after EndDate.



It works, and after creating a covering index the speed is ok, but I think there might be a way to reduce the number of roundtrips to the DB. Do you have any idea?










share|improve this question







New contributor




Robert is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
















  • 1





    Hi, could you add the query you tried,your sql server version, and if possible the table definition + sample data?

    – Randi Vertongen
    4 hours ago











  • Do you notice any performance issues as a result of the three trips to the database? Unless it's causing an issue, your existing solution might be good enough. There are always windowing functions you can use (SQL Server 2012+) if you really want to reduce the number of trips, but basically you need to decide if it's worth the effort.

    – Randolph West
    3 hours ago











  • Please edit the question andd the query you use. It's not clear if you query for a single StationID, for a single (StationID, DatapointID) combination or for all stations in a specific time range.

    – ypercubeᵀᴹ
    3 hours ago











  • Thanks for your comments. I did not show my queries because I did not want to bias your answers, they are very basic select/select top where thingies anyway. I need to query for a single StationId and a single DatapointId at a time.

    – Robert
    3 hours ago











  • @RandolphWest: The performance is ok, but the chance of reducing the execution time by 2/3 is very tempting. Thanks for mentioning windowing functions, I'll have a look at that!

    – Robert
    3 hours ago














1












1








1








We have a SQL Server DB that contains a large table (>100M rows) with archive values, basically in the form of [Id], [StationId], [DatapointId], [Timestamp], [Value]. As the stations do not get polled, there aren't any regular intervals at which a station sends a datapoint, so the timestamps are set to arbitrary times.



For our web visualization, I need to extract entries from this table for a pannable chart that I'm building with D3.js. I need to query by StationId, DatapointId, StartDate and EndDate. This is simple and works as expected, but for the line chart that it feeds, I do need additional data, namely the first value before the chosen time interval, and (if there is one) the first value after the interval. This is neccessary to draw the line from the left resp. right boundary of the chart to the first/last value within the interval (otherwise the data within the chart would look somewhat "isolated" because the line stops before the charts boundaries, like there's no data before or after the values in the chosen interval).



At the moment I need to run 3 queries: one to get the data within the interval, one to retrieve the first matching row before StartDate, and anotherone to get the first matching row after EndDate.



It works, and after creating a covering index the speed is ok, but I think there might be a way to reduce the number of roundtrips to the DB. Do you have any idea?










share|improve this question







New contributor




Robert is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












We have a SQL Server DB that contains a large table (>100M rows) with archive values, basically in the form of [Id], [StationId], [DatapointId], [Timestamp], [Value]. As the stations do not get polled, there aren't any regular intervals at which a station sends a datapoint, so the timestamps are set to arbitrary times.



For our web visualization, I need to extract entries from this table for a pannable chart that I'm building with D3.js. I need to query by StationId, DatapointId, StartDate and EndDate. This is simple and works as expected, but for the line chart that it feeds, I do need additional data, namely the first value before the chosen time interval, and (if there is one) the first value after the interval. This is neccessary to draw the line from the left resp. right boundary of the chart to the first/last value within the interval (otherwise the data within the chart would look somewhat "isolated" because the line stops before the charts boundaries, like there's no data before or after the values in the chosen interval).



At the moment I need to run 3 queries: one to get the data within the interval, one to retrieve the first matching row before StartDate, and anotherone to get the first matching row after EndDate.



It works, and after creating a covering index the speed is ok, but I think there might be a way to reduce the number of roundtrips to the DB. Do you have any idea?







sql-server query-performance optimization






share|improve this question







New contributor




Robert is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question







New contributor




Robert is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question






New contributor




Robert is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 4 hours ago









RobertRobert

1063




1063




New contributor




Robert is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Robert is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Robert is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








  • 1





    Hi, could you add the query you tried,your sql server version, and if possible the table definition + sample data?

    – Randi Vertongen
    4 hours ago











  • Do you notice any performance issues as a result of the three trips to the database? Unless it's causing an issue, your existing solution might be good enough. There are always windowing functions you can use (SQL Server 2012+) if you really want to reduce the number of trips, but basically you need to decide if it's worth the effort.

    – Randolph West
    3 hours ago











  • Please edit the question andd the query you use. It's not clear if you query for a single StationID, for a single (StationID, DatapointID) combination or for all stations in a specific time range.

    – ypercubeᵀᴹ
    3 hours ago











  • Thanks for your comments. I did not show my queries because I did not want to bias your answers, they are very basic select/select top where thingies anyway. I need to query for a single StationId and a single DatapointId at a time.

    – Robert
    3 hours ago











  • @RandolphWest: The performance is ok, but the chance of reducing the execution time by 2/3 is very tempting. Thanks for mentioning windowing functions, I'll have a look at that!

    – Robert
    3 hours ago














  • 1





    Hi, could you add the query you tried,your sql server version, and if possible the table definition + sample data?

    – Randi Vertongen
    4 hours ago











  • Do you notice any performance issues as a result of the three trips to the database? Unless it's causing an issue, your existing solution might be good enough. There are always windowing functions you can use (SQL Server 2012+) if you really want to reduce the number of trips, but basically you need to decide if it's worth the effort.

    – Randolph West
    3 hours ago











  • Please edit the question andd the query you use. It's not clear if you query for a single StationID, for a single (StationID, DatapointID) combination or for all stations in a specific time range.

    – ypercubeᵀᴹ
    3 hours ago











  • Thanks for your comments. I did not show my queries because I did not want to bias your answers, they are very basic select/select top where thingies anyway. I need to query for a single StationId and a single DatapointId at a time.

    – Robert
    3 hours ago











  • @RandolphWest: The performance is ok, but the chance of reducing the execution time by 2/3 is very tempting. Thanks for mentioning windowing functions, I'll have a look at that!

    – Robert
    3 hours ago








1




1





Hi, could you add the query you tried,your sql server version, and if possible the table definition + sample data?

– Randi Vertongen
4 hours ago





Hi, could you add the query you tried,your sql server version, and if possible the table definition + sample data?

– Randi Vertongen
4 hours ago













Do you notice any performance issues as a result of the three trips to the database? Unless it's causing an issue, your existing solution might be good enough. There are always windowing functions you can use (SQL Server 2012+) if you really want to reduce the number of trips, but basically you need to decide if it's worth the effort.

– Randolph West
3 hours ago





Do you notice any performance issues as a result of the three trips to the database? Unless it's causing an issue, your existing solution might be good enough. There are always windowing functions you can use (SQL Server 2012+) if you really want to reduce the number of trips, but basically you need to decide if it's worth the effort.

– Randolph West
3 hours ago













Please edit the question andd the query you use. It's not clear if you query for a single StationID, for a single (StationID, DatapointID) combination or for all stations in a specific time range.

– ypercubeᵀᴹ
3 hours ago





Please edit the question andd the query you use. It's not clear if you query for a single StationID, for a single (StationID, DatapointID) combination or for all stations in a specific time range.

– ypercubeᵀᴹ
3 hours ago













Thanks for your comments. I did not show my queries because I did not want to bias your answers, they are very basic select/select top where thingies anyway. I need to query for a single StationId and a single DatapointId at a time.

– Robert
3 hours ago





Thanks for your comments. I did not show my queries because I did not want to bias your answers, they are very basic select/select top where thingies anyway. I need to query for a single StationId and a single DatapointId at a time.

– Robert
3 hours ago













@RandolphWest: The performance is ok, but the chance of reducing the execution time by 2/3 is very tempting. Thanks for mentioning windowing functions, I'll have a look at that!

– Robert
3 hours ago





@RandolphWest: The performance is ok, but the chance of reducing the execution time by 2/3 is very tempting. Thanks for mentioning windowing functions, I'll have a look at that!

– Robert
3 hours ago










2 Answers
2






active

oldest

votes


















1














I assume you query for all data (from all stations) in a specific time range.



You can probably write this with window functions (and it might be more efficient) but here is one method, with OUTER APPLY.



(The ds subquery is only used to get a list of distinct StationID. It should be replaced with the Stations table you likely have):



SELECT
ds.[StationID], -- station
st.ExtendedStartDate, -- extended start and
en.ExtendedEndDate -- and end dates

tt.[Timestamp], -- timestamps and data
tt.[DatapointId],
tt.[Value]
FROM
( SELECT DISTINCT [StationID]
FROM ArchiveTable
) AS ds
OUTER APPLY
( SELECT TOP (1) s.[Timestamp] AS ExtendedStartDate
FROM ArchiveTable AS s
WHERE s.[StationId] = ds.[StationId]
AND s.[Timestamp] < @StartDate
ORDER BY s.[Timestamp] DESC
) AS st
OUTER APPLY
( SELECT TOP (1) e.[Timestamp] AS ExtendedEndDate
FROM ArchiveTable AS e
WHERE e.[StationId] = ds.[StationId]
AND e.[Timestamp] > @EndDate
ORDER BY e.[Timestamp] ASC
) AS en
OUTER APPLY
( SELECT t.*
FROM ArchiveTable AS t
WHERE t.[StationId] = ds.[StationId]
AND t.[Timestamp] >= COALESCE(st.ExtendedStartDate, @StartDate)
AND t.[Timestamp] <= COALESCE(en.ExtendedEndDate, @EndDate)
) AS tt ;





share|improve this answer

































    1














    Taking roundtrips to the database should not be an issue, if you want to send them to the db as one query, you could do that by using CTE's and UNION ALL operators.




    I need to query for a single StationId and a single DatapointId at a
    time




    The query below filters on StationId, DatapointID and the StartDate and EndDate using the timestamp column.



    --Filter params

    DECLARE @startdate datetime2 = '2019-02-20 8:48:08.633'
    DECLARE @EndDate datetime2 = '2019-02-20 10:48:08.633'
    DECLARE @stationid int = 1
    DECLARE @DatapointId int = 1

    --Query

    ;WITH CTE AS
    (
    SELECT TOP(1) [StationId],[DatapointId],[TimeStamp]
    FROM PollingTable
    WHERE [TimeStamp] < @startdate
    AND StationId = @stationId
    AND [DatapointId] = @Datapointid
    ORDER BY [TimeStamp] desc
    )
    ,CTE2 AS
    (
    SELECT TOP(1) [StationId],[DatapointId],[TimeStamp]
    FROM PollingTable
    WHERE [TimeStamp] > @EndDate
    AND StationId = @stationId
    AND [DatapointId] = @Datapointid
    ORDER BY [TimeStamp] asc
    )
    SELECT [StationId],[DatapointId],[TimeStamp]
    FROM CTE
    UNION ALL
    SELECT [StationId],[DatapointId],[TimeStamp]
    FROM PollingTable
    WHERE [TimeStamp] >= @startdate
    AND [TimeStamp] <= @EndDate
    AND StationId = @stationId
    AND [DatapointId] = @Datapointid
    UNION ALL
    SELECT [StationId],[DatapointId],[TimeStamp]
    FROM CTE2;


    Afterwards, this index was added



    CREATE INDEX IX_StationId_DatapointId_TimeStamp on PollingTable(StationId,DatapointId,TimeStamp)


    Resulting in seeks on my end, but you might have to swap columns around depending on how your dataset is distributed. My dataset is nowhere near yours.



    enter image description here






    share|improve this answer

























      Your Answer








      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "182"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: false,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });






      Robert is a new contributor. Be nice, and check out our Code of Conduct.










      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f230354%2fhow-to-most-effectively-get-the-first-preceding-subsequent-entry-outside-a-given%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      I assume you query for all data (from all stations) in a specific time range.



      You can probably write this with window functions (and it might be more efficient) but here is one method, with OUTER APPLY.



      (The ds subquery is only used to get a list of distinct StationID. It should be replaced with the Stations table you likely have):



      SELECT
      ds.[StationID], -- station
      st.ExtendedStartDate, -- extended start and
      en.ExtendedEndDate -- and end dates

      tt.[Timestamp], -- timestamps and data
      tt.[DatapointId],
      tt.[Value]
      FROM
      ( SELECT DISTINCT [StationID]
      FROM ArchiveTable
      ) AS ds
      OUTER APPLY
      ( SELECT TOP (1) s.[Timestamp] AS ExtendedStartDate
      FROM ArchiveTable AS s
      WHERE s.[StationId] = ds.[StationId]
      AND s.[Timestamp] < @StartDate
      ORDER BY s.[Timestamp] DESC
      ) AS st
      OUTER APPLY
      ( SELECT TOP (1) e.[Timestamp] AS ExtendedEndDate
      FROM ArchiveTable AS e
      WHERE e.[StationId] = ds.[StationId]
      AND e.[Timestamp] > @EndDate
      ORDER BY e.[Timestamp] ASC
      ) AS en
      OUTER APPLY
      ( SELECT t.*
      FROM ArchiveTable AS t
      WHERE t.[StationId] = ds.[StationId]
      AND t.[Timestamp] >= COALESCE(st.ExtendedStartDate, @StartDate)
      AND t.[Timestamp] <= COALESCE(en.ExtendedEndDate, @EndDate)
      ) AS tt ;





      share|improve this answer






























        1














        I assume you query for all data (from all stations) in a specific time range.



        You can probably write this with window functions (and it might be more efficient) but here is one method, with OUTER APPLY.



        (The ds subquery is only used to get a list of distinct StationID. It should be replaced with the Stations table you likely have):



        SELECT
        ds.[StationID], -- station
        st.ExtendedStartDate, -- extended start and
        en.ExtendedEndDate -- and end dates

        tt.[Timestamp], -- timestamps and data
        tt.[DatapointId],
        tt.[Value]
        FROM
        ( SELECT DISTINCT [StationID]
        FROM ArchiveTable
        ) AS ds
        OUTER APPLY
        ( SELECT TOP (1) s.[Timestamp] AS ExtendedStartDate
        FROM ArchiveTable AS s
        WHERE s.[StationId] = ds.[StationId]
        AND s.[Timestamp] < @StartDate
        ORDER BY s.[Timestamp] DESC
        ) AS st
        OUTER APPLY
        ( SELECT TOP (1) e.[Timestamp] AS ExtendedEndDate
        FROM ArchiveTable AS e
        WHERE e.[StationId] = ds.[StationId]
        AND e.[Timestamp] > @EndDate
        ORDER BY e.[Timestamp] ASC
        ) AS en
        OUTER APPLY
        ( SELECT t.*
        FROM ArchiveTable AS t
        WHERE t.[StationId] = ds.[StationId]
        AND t.[Timestamp] >= COALESCE(st.ExtendedStartDate, @StartDate)
        AND t.[Timestamp] <= COALESCE(en.ExtendedEndDate, @EndDate)
        ) AS tt ;





        share|improve this answer




























          1












          1








          1







          I assume you query for all data (from all stations) in a specific time range.



          You can probably write this with window functions (and it might be more efficient) but here is one method, with OUTER APPLY.



          (The ds subquery is only used to get a list of distinct StationID. It should be replaced with the Stations table you likely have):



          SELECT
          ds.[StationID], -- station
          st.ExtendedStartDate, -- extended start and
          en.ExtendedEndDate -- and end dates

          tt.[Timestamp], -- timestamps and data
          tt.[DatapointId],
          tt.[Value]
          FROM
          ( SELECT DISTINCT [StationID]
          FROM ArchiveTable
          ) AS ds
          OUTER APPLY
          ( SELECT TOP (1) s.[Timestamp] AS ExtendedStartDate
          FROM ArchiveTable AS s
          WHERE s.[StationId] = ds.[StationId]
          AND s.[Timestamp] < @StartDate
          ORDER BY s.[Timestamp] DESC
          ) AS st
          OUTER APPLY
          ( SELECT TOP (1) e.[Timestamp] AS ExtendedEndDate
          FROM ArchiveTable AS e
          WHERE e.[StationId] = ds.[StationId]
          AND e.[Timestamp] > @EndDate
          ORDER BY e.[Timestamp] ASC
          ) AS en
          OUTER APPLY
          ( SELECT t.*
          FROM ArchiveTable AS t
          WHERE t.[StationId] = ds.[StationId]
          AND t.[Timestamp] >= COALESCE(st.ExtendedStartDate, @StartDate)
          AND t.[Timestamp] <= COALESCE(en.ExtendedEndDate, @EndDate)
          ) AS tt ;





          share|improve this answer















          I assume you query for all data (from all stations) in a specific time range.



          You can probably write this with window functions (and it might be more efficient) but here is one method, with OUTER APPLY.



          (The ds subquery is only used to get a list of distinct StationID. It should be replaced with the Stations table you likely have):



          SELECT
          ds.[StationID], -- station
          st.ExtendedStartDate, -- extended start and
          en.ExtendedEndDate -- and end dates

          tt.[Timestamp], -- timestamps and data
          tt.[DatapointId],
          tt.[Value]
          FROM
          ( SELECT DISTINCT [StationID]
          FROM ArchiveTable
          ) AS ds
          OUTER APPLY
          ( SELECT TOP (1) s.[Timestamp] AS ExtendedStartDate
          FROM ArchiveTable AS s
          WHERE s.[StationId] = ds.[StationId]
          AND s.[Timestamp] < @StartDate
          ORDER BY s.[Timestamp] DESC
          ) AS st
          OUTER APPLY
          ( SELECT TOP (1) e.[Timestamp] AS ExtendedEndDate
          FROM ArchiveTable AS e
          WHERE e.[StationId] = ds.[StationId]
          AND e.[Timestamp] > @EndDate
          ORDER BY e.[Timestamp] ASC
          ) AS en
          OUTER APPLY
          ( SELECT t.*
          FROM ArchiveTable AS t
          WHERE t.[StationId] = ds.[StationId]
          AND t.[Timestamp] >= COALESCE(st.ExtendedStartDate, @StartDate)
          AND t.[Timestamp] <= COALESCE(en.ExtendedEndDate, @EndDate)
          ) AS tt ;






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 3 hours ago

























          answered 3 hours ago









          ypercubeᵀᴹypercubeᵀᴹ

          76.8k11132214




          76.8k11132214

























              1














              Taking roundtrips to the database should not be an issue, if you want to send them to the db as one query, you could do that by using CTE's and UNION ALL operators.




              I need to query for a single StationId and a single DatapointId at a
              time




              The query below filters on StationId, DatapointID and the StartDate and EndDate using the timestamp column.



              --Filter params

              DECLARE @startdate datetime2 = '2019-02-20 8:48:08.633'
              DECLARE @EndDate datetime2 = '2019-02-20 10:48:08.633'
              DECLARE @stationid int = 1
              DECLARE @DatapointId int = 1

              --Query

              ;WITH CTE AS
              (
              SELECT TOP(1) [StationId],[DatapointId],[TimeStamp]
              FROM PollingTable
              WHERE [TimeStamp] < @startdate
              AND StationId = @stationId
              AND [DatapointId] = @Datapointid
              ORDER BY [TimeStamp] desc
              )
              ,CTE2 AS
              (
              SELECT TOP(1) [StationId],[DatapointId],[TimeStamp]
              FROM PollingTable
              WHERE [TimeStamp] > @EndDate
              AND StationId = @stationId
              AND [DatapointId] = @Datapointid
              ORDER BY [TimeStamp] asc
              )
              SELECT [StationId],[DatapointId],[TimeStamp]
              FROM CTE
              UNION ALL
              SELECT [StationId],[DatapointId],[TimeStamp]
              FROM PollingTable
              WHERE [TimeStamp] >= @startdate
              AND [TimeStamp] <= @EndDate
              AND StationId = @stationId
              AND [DatapointId] = @Datapointid
              UNION ALL
              SELECT [StationId],[DatapointId],[TimeStamp]
              FROM CTE2;


              Afterwards, this index was added



              CREATE INDEX IX_StationId_DatapointId_TimeStamp on PollingTable(StationId,DatapointId,TimeStamp)


              Resulting in seeks on my end, but you might have to swap columns around depending on how your dataset is distributed. My dataset is nowhere near yours.



              enter image description here






              share|improve this answer






























                1














                Taking roundtrips to the database should not be an issue, if you want to send them to the db as one query, you could do that by using CTE's and UNION ALL operators.




                I need to query for a single StationId and a single DatapointId at a
                time




                The query below filters on StationId, DatapointID and the StartDate and EndDate using the timestamp column.



                --Filter params

                DECLARE @startdate datetime2 = '2019-02-20 8:48:08.633'
                DECLARE @EndDate datetime2 = '2019-02-20 10:48:08.633'
                DECLARE @stationid int = 1
                DECLARE @DatapointId int = 1

                --Query

                ;WITH CTE AS
                (
                SELECT TOP(1) [StationId],[DatapointId],[TimeStamp]
                FROM PollingTable
                WHERE [TimeStamp] < @startdate
                AND StationId = @stationId
                AND [DatapointId] = @Datapointid
                ORDER BY [TimeStamp] desc
                )
                ,CTE2 AS
                (
                SELECT TOP(1) [StationId],[DatapointId],[TimeStamp]
                FROM PollingTable
                WHERE [TimeStamp] > @EndDate
                AND StationId = @stationId
                AND [DatapointId] = @Datapointid
                ORDER BY [TimeStamp] asc
                )
                SELECT [StationId],[DatapointId],[TimeStamp]
                FROM CTE
                UNION ALL
                SELECT [StationId],[DatapointId],[TimeStamp]
                FROM PollingTable
                WHERE [TimeStamp] >= @startdate
                AND [TimeStamp] <= @EndDate
                AND StationId = @stationId
                AND [DatapointId] = @Datapointid
                UNION ALL
                SELECT [StationId],[DatapointId],[TimeStamp]
                FROM CTE2;


                Afterwards, this index was added



                CREATE INDEX IX_StationId_DatapointId_TimeStamp on PollingTable(StationId,DatapointId,TimeStamp)


                Resulting in seeks on my end, but you might have to swap columns around depending on how your dataset is distributed. My dataset is nowhere near yours.



                enter image description here






                share|improve this answer




























                  1












                  1








                  1







                  Taking roundtrips to the database should not be an issue, if you want to send them to the db as one query, you could do that by using CTE's and UNION ALL operators.




                  I need to query for a single StationId and a single DatapointId at a
                  time




                  The query below filters on StationId, DatapointID and the StartDate and EndDate using the timestamp column.



                  --Filter params

                  DECLARE @startdate datetime2 = '2019-02-20 8:48:08.633'
                  DECLARE @EndDate datetime2 = '2019-02-20 10:48:08.633'
                  DECLARE @stationid int = 1
                  DECLARE @DatapointId int = 1

                  --Query

                  ;WITH CTE AS
                  (
                  SELECT TOP(1) [StationId],[DatapointId],[TimeStamp]
                  FROM PollingTable
                  WHERE [TimeStamp] < @startdate
                  AND StationId = @stationId
                  AND [DatapointId] = @Datapointid
                  ORDER BY [TimeStamp] desc
                  )
                  ,CTE2 AS
                  (
                  SELECT TOP(1) [StationId],[DatapointId],[TimeStamp]
                  FROM PollingTable
                  WHERE [TimeStamp] > @EndDate
                  AND StationId = @stationId
                  AND [DatapointId] = @Datapointid
                  ORDER BY [TimeStamp] asc
                  )
                  SELECT [StationId],[DatapointId],[TimeStamp]
                  FROM CTE
                  UNION ALL
                  SELECT [StationId],[DatapointId],[TimeStamp]
                  FROM PollingTable
                  WHERE [TimeStamp] >= @startdate
                  AND [TimeStamp] <= @EndDate
                  AND StationId = @stationId
                  AND [DatapointId] = @Datapointid
                  UNION ALL
                  SELECT [StationId],[DatapointId],[TimeStamp]
                  FROM CTE2;


                  Afterwards, this index was added



                  CREATE INDEX IX_StationId_DatapointId_TimeStamp on PollingTable(StationId,DatapointId,TimeStamp)


                  Resulting in seeks on my end, but you might have to swap columns around depending on how your dataset is distributed. My dataset is nowhere near yours.



                  enter image description here






                  share|improve this answer















                  Taking roundtrips to the database should not be an issue, if you want to send them to the db as one query, you could do that by using CTE's and UNION ALL operators.




                  I need to query for a single StationId and a single DatapointId at a
                  time




                  The query below filters on StationId, DatapointID and the StartDate and EndDate using the timestamp column.



                  --Filter params

                  DECLARE @startdate datetime2 = '2019-02-20 8:48:08.633'
                  DECLARE @EndDate datetime2 = '2019-02-20 10:48:08.633'
                  DECLARE @stationid int = 1
                  DECLARE @DatapointId int = 1

                  --Query

                  ;WITH CTE AS
                  (
                  SELECT TOP(1) [StationId],[DatapointId],[TimeStamp]
                  FROM PollingTable
                  WHERE [TimeStamp] < @startdate
                  AND StationId = @stationId
                  AND [DatapointId] = @Datapointid
                  ORDER BY [TimeStamp] desc
                  )
                  ,CTE2 AS
                  (
                  SELECT TOP(1) [StationId],[DatapointId],[TimeStamp]
                  FROM PollingTable
                  WHERE [TimeStamp] > @EndDate
                  AND StationId = @stationId
                  AND [DatapointId] = @Datapointid
                  ORDER BY [TimeStamp] asc
                  )
                  SELECT [StationId],[DatapointId],[TimeStamp]
                  FROM CTE
                  UNION ALL
                  SELECT [StationId],[DatapointId],[TimeStamp]
                  FROM PollingTable
                  WHERE [TimeStamp] >= @startdate
                  AND [TimeStamp] <= @EndDate
                  AND StationId = @stationId
                  AND [DatapointId] = @Datapointid
                  UNION ALL
                  SELECT [StationId],[DatapointId],[TimeStamp]
                  FROM CTE2;


                  Afterwards, this index was added



                  CREATE INDEX IX_StationId_DatapointId_TimeStamp on PollingTable(StationId,DatapointId,TimeStamp)


                  Resulting in seeks on my end, but you might have to swap columns around depending on how your dataset is distributed. My dataset is nowhere near yours.



                  enter image description here







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 2 hours ago

























                  answered 3 hours ago









                  Randi VertongenRandi Vertongen

                  2,866721




                  2,866721






















                      Robert is a new contributor. Be nice, and check out our Code of Conduct.










                      draft saved

                      draft discarded


















                      Robert is a new contributor. Be nice, and check out our Code of Conduct.













                      Robert is a new contributor. Be nice, and check out our Code of Conduct.












                      Robert is a new contributor. Be nice, and check out our Code of Conduct.
















                      Thanks for contributing an answer to Database Administrators Stack Exchange!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fdba.stackexchange.com%2fquestions%2f230354%2fhow-to-most-effectively-get-the-first-preceding-subsequent-entry-outside-a-given%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Szabolcs (Ungheria) Altri progetti | Menu di navigazione48°10′14.56″N 21°29′33.14″E /...

                      Discografia di Klaus Schulze Indice Album in studio | Album dal vivo | Singoli | Antologie | Colonne...

                      How to make inet_server_addr() return localhost in spite of ::1/128RETURN NEXT in Postgres FunctionConnect to...