(Edit1: упрощенный, Edit2: более широкий охват)
Решения для любой длина массива.Также возвращает все попадания, даже в нескольких позициях в одном или нескольких массивах одновременно.
Если вам известна фиксированная длина одномерного массива, вы можете жестко закодировать егов generate_series()
, для самого простого и быстрого решения :
SELECT id, c1[i], c2[i], c3[i]
FROM tbl, generate_series(1, 3) i
WHERE c3[i] = 200;
Если все массивы в c3
имеют одно и то же неизвестноедлина , вы можете обобщить с очень небольшими затратами:
SELECT id, c1[i], c2[i], c3[i]
FROM tbl, generate_subscripts((SELECT c3 FROM tbl LIMIT 1), 1) s(i)
WHERE c3[i] = 200;
Обратите внимание, что я использую удобную функцию generate_subscripts()
здесь.
Для больших индексов, чем верхняяпредел, элементы массива просто NULL
и выпадают из запроса.
Если неизвестная длина массива в c3
на самом деле изменяется Вы можете обобщить еще немного, с более высокой стоимостью:
SELECT id, c1[i], c2[i], c3[i]
FROM tbl
FROM tbl, generate_series(1, (SELECT max(array_upper(c3, 1)) FROM tbl)) s(i)
WHERE c3[i] = 200;
Наконец, для нестандартных индексов массива кроме того, то же самое можно сделать так:
SELECT id, c1[i], c2[i], c3[i]
FROM tbl
, generate_subscripts((SELECT c3 FROM tbl
ORDER BY array_length(c3,1) DESC LIMIT 1), 1) s(i)
WHERE c3[i] = 200;
Мгновенный испытательный стенд:
WITH tbl (id, c1, c2, c3) AS (
VALUES
(1, '{1, 2, 3}'::int[], '{10, 20, 30}'::int[], '{100, 200, 300}'::int[])
,(2, '{4, 5, 6}', '{11, 22, 33}', '{111, 222, 333}')
-- un-comment to test 333 in all positions of c3 and varying array length
-- ,(3, '{7, 8, 9, 10}', '{14, 25}', '{333, 333, 333, 333}')
)
SELECT id, c1[i], c2[i], c3[i]
FROM tbl
,generate_subscripts((SELECT c3 FROM tbl
ORDER BY array_length(c3,1) DESC LIMIT 1), 1) s(i)
WHERE c3[i] = 333;