0

I have constructed a naive query that works for my application, which returns multiple values from a table that contains an array of reals.

SELECT 
  "timestamp" AS "time",
  type as metric,
  id,
  values[80],
  values[81],
  values[82],
  values[83],
  values[84],
  values[85],
  values[86],
  values[87],
  values[88],
  values[89],
  values[91],
  values[92],
  values[93],
  values[94],
  values[95],
  values[96],
  values[97],
  values[98],
  values[99],
  values[100],
  values[101]

FROM test_table
WHERE
  "timestamp" BETWEEN '2021-04-03T15:05:56.928Z' AND '2021-04-03T15:10:56.928Z'
ORDER BY 1

However, for obvious reasons, I want to avoid long lists of values[n] in my query, especially as in fact I need to get up to 1000 values.

I know that it is possible to iterate over an array but everything I try to replace the list of array subscripts along the lines of

  FOR i IN ARRAY values
  LOOP 
      values [i]
  END LOOP;

errors out.

As an obvious SQL noob, can someone suggest how this might query might be done more elegantly?

8
  • Why not just return the array? Commented Apr 4, 2021 at 2:01
  • because the result is fed as bucketed timeseries data into Grafana which expects a set of values Commented Apr 4, 2021 at 3:00
  • 1
    You don't show a set of values. You show a row with many columns. What result do you need exactly? Commented Apr 4, 2021 at 3:38
  • I can imagine doing this in multiple steps: - turn the single row that you want to get from test_table into a table, expanding the arrai values into one value per row in this new table, using generate_subscripts(): postgresql.org/docs/9.1/… - use a pivot to turn this table back into a single row, using crosstab(): stackoverflow.com/questions/3002499/postgresql-crosstab-query/… Commented Apr 4, 2021 at 4:14
  • @moilejter this sounds a bit beyond my very basic SQL skills, but I will have a go, thanks! Commented Apr 4, 2021 at 5:14

1 Answer 1

0

You can use PostgreSQL's unnest for this purpose. It's not gonna be exactly the same as your example. The values from the array won't be unpacked in more columns, they will be unpacked in more rows, instead.

Here are the docs.

Example

SELECT 
  "timestamp" AS "time",
  type as metric,
  id,
  unnest(values[80:101])
FROM test_table
WHERE
  "timestamp" BETWEEN '2021-04-03T15:05:56.928Z' AND '2021-04-03T15:10:56.928Z'
ORDER BY 1

The timestamp, type, and id will be duplicated across the rows.

Note that the slicing of the array is inclusive for both bounds (unlike the one in Python). See more in this answer by mu is too short.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.