Для PostgreSQL 8.4 +
Вы можете решить эту проблему с помощью unnest()
и LEFT JOIN
:
SELECT x.barcode
,p.product_id
,CASE WHEN p.name IS NULL THEN 'NO' ELSE 'YES' END AS product_name_exists
FROM (SELECT unnest (
'{679046,679047,679082,679228,679230,679235,679236,'
'679238,679328,679330,679528,679608,679609,679647,'
'679727,679728,679730,679808,679809,679828,679830}'::text[]) AS barcode
) x
LEFT JOIN product USING (barcode);
- unnest () генерирует одну строку на элемент ARRAY.Он был представлен в PostgreSQL 8.4.
- LEFT JOIN обеспечивает отображение каждого
barcode
, даже если не найдено ни одного соответствующего продукта.
Будьте в курсеЭто может быть две причины отсутствия названия продукта: 1) Штрих-код не найден.2) product.name IS NULL
.
Возможно, вы захотите добавить NOT NULL constraint
к столбцу name
в вашей таблице product
- если у вас его нет.
Для PostgreSQL8.3
Используйте regexp_split_to_table ()
SELECT x.barcode
,p.product_id
,CASE WHEN p.name IS NULL THEN 'NO' ELSE 'YES' END AS product_name_exists
FROM (SELECT regexp_split_to_table (
'679046,679047,679082,679228,679230,679235,679236,'
'679238,679328,679330,679528,679608,679609,679647,'
'679727,679728,679730,679808,679809,679828,679830', ',') AS barcode
) x
LEFT JOIN product USING (barcode);
- Альтернативой будет regexp_split_to_table () , представленная в PostgreSQL 8.3.
- Обратите внимание, какчасти строки объединяются автоматически.Не очень известная функция, определенная стандартом SQL.
Для PostgreSQL 8.2
Пока не существует ни одной из функций, генерирующих SET. Рассмотрите возможность обновления до более новой версии!PostgreSQL 8.2 достигает конца срока службы в декабре 2011 года .
Универсальное решение для любого количества штрих-кодов (медленно для очень большого числа штрих-кодов):
SELECT x.barcode
,p.product_id
,CASE WHEN p.name IS NULL THEN 'NO' ELSE 'YES' END AS product_name_exists
FROM (
SELECT a[i] AS barcode
FROM (
SELECT a.a, generate_series(1, array_upper(a.a, 1)) AS i
FROM (
SELECT
'{679046,679047,679082,679228,679230,679235,679236,'
'679238,679328,679330,679528,679608,679609,679647,'
'679727,679728,679730,679808,679809,679828,679830}'::text[] AS a
) a
) i
)x
LEFT JOIN product USING (barcode);
Или явная конструкция SET с UNION ALL:
SELECT x.barcode
,p.product_id
,CASE WHEN p.name IS NULL THEN 'NO' ELSE 'YES' END AS product_name_exists
FROM (
SELECT '679046' AS barcode
UNION ALL SELECT '679047'
UNION ALL SELECT '679082'
UNION ALL SELECT '679228'
UNION ALL SELECT '679230'
UNION ALL SELECT '679235'
UNION ALL SELECT '679236'
-- ...
) x
LEFT JOIN product USING (barcode);