0

I have the following query:

SELECT d.currentDate, t.ConfigId, t.value as value
FROM    #Dates AS d
        OUTER APPLY
        (   SELECT  t.value as value, t.FK_ShipDataSubsystemConfigId
            FROM    myTable AS t
            WHERE   t.[Timestamp] <= d.currentDate and t.ConfigId in (' + @IDList + ')
            and t.FK_DataSystemId <> 1
        ) AS t 
GROUP BY d.currentDate, t.ConfigId
)

where Dates is just a table holding a bunch of datetimes I am using to ensure I get the data at the intervals I need.

My problem is with the group by clause. The query doesn't work as is because value is not in the group by or an aggregate function. I tried grouping by value also to make the error go away, but it just gives me every single date in the interval I am selecting on matched to every single value -- not what I want. I should end up with a table with one row for each date/ConfigId pairing.

When I remove value from the select and just get the date and the ConfigId, it works fine. I get the exact number of rows I should be getting.

The table I'm pulling from looks like this:

PK_DataId    Timestamp        value     ConfigId
1            1/1/2015 12:00   234       5
2            1/1/2015 12:01   456       4

I am expecting to get back this:

Timestamp            value        ConfigId
1/1/2015 12:00:00    234          5
1/1/2015 12:00:00    456          4

Where I have a value for each configId/date pair from every fifteen minutes. When I add max(value) I only get one value for every time instead of different ones. When I group by value I get millions of rows, it looks like I am getting one row for each timestamp matched with each value from any other timestamp. I don't really understand what is happening.

How can I get those results while also selecting value?

eddie_cat
  • 2,527
  • 4
  • 25
  • 43

2 Answers2

1

If I understand correctly, you just want top 1 in the apply:

SELECT d.currentDate, t.ConfigId, t.value as value
FROM #Dates d OUTER APPLY
     (SELECT  TOP 1 t.value as value, t.FK_ShipDataSubsystemConfigId
      FROM    myTable AS t
      WHERE   t.[Timestamp] <= d.currentDate and
              t.ConfigId in (' + @IDList + ') and
              t.FK_DataSystemId <> 1
     ORDER BY t.[Timestamp] DESC
    ) t ;

EDIT:

If you need one row for each config and time:

SELECT d.currentDate, t.ConfigId, t.value as value
FROM #Dates d CROSS JOIN
     (SELECT DISTINCT FK_ShipDataSubsystemConfigId
      FROM myTable
      WHERE t.ConfigId in (' + @IDList + ')
     ) c OUTER APPLY
     (SELECT  TOP 1 t.value as value, t.FK_ShipDataSubsystemConfigId
      FROM    myTable AS t
      WHERE   t.[Timestamp] <= d.currentDate and
              t.ConfigId = c.FK_ShipDataSubsystemConfigId and
              t.FK_DataSystemId <> 1
      ORDER BY t.[Timestamp] DESC
     ) t ;

Same basic idea, but this needs to generate all the rows for all configs and the dates before the outer apply.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
  • It's closer, I am getting different values now. But I am only getting one row for each time, when I should have one row for each time/configId. – eddie_cat Jul 16 '15 at 19:16
0

Without real data is really hard to understand your question.

Im going to guess you dont want Aggregeted function like.

SELECT d.currentDate, t.ConfigId, 
  MAX(t.value) as maxvalue, 
  MIN(t.value) as minvalue,
  COUNT(t.value) as totalvalue

So im going with you are looking for

simulating-group-concat-mysql-function-in-sql-server

ANDY   |  A100
ANDY   |  B391
ANDY   |  X010
TOM    |  A100
TOM    |  A510

returns:

ANDY   |  A100 / B391 / X010
TOM    |  A100 / A510
Community
  • 1
  • 1
Juan Carlos Oropeza
  • 47,252
  • 12
  • 78
  • 118