在 string_agg 函数中使用 if 语句 - postgreSQL
Using if statement in string_agg function - postreSQL
查询如下
WITH notes AS (
SELECT 891090 Order_ID, False customer_billing, false commander, true agent
UNION ALL
SELECT 891091, false, true, true
UNION ALL
SELECT 891091, true, false, false)
SELECT
n.order_id,
string_Agg(distinct CASE
WHEN n.customer_billing = TRUE THEN 'AR (Customer Billing)'
WHEN n.commander = TRUE THEN 'AP (Commander)'
WHEN n.agent = TRUE THEN 'AP (Agent)'
ELSE NULL
END,', ') AS finance
FROM notes n
WHERE
n.order_id = 891091 AND (n.customer_billing = TRUE or n.commander = TRUE or n.agent = TRUE)
GROUP BY ORDER_ID
如您所见,有两条记录 order_id 为 891091.
- 第一个 891091 条记录
commander
和 agent
设置为真
- 第二个 891091 记录已
customer_billing
设置为 true
由于使用了switch case,所以只考虑第一个真值和returnscommander
,不考虑agent
.
所以输出变成
order_id finance
891091 AP (Commander), AR (Customer Billing)
我需要考虑记录中的所有真实值,以便输出变为
order_id finance
891091 AP (Commander), AP (Agent), AR (Customer Billing)
我最初的想法是使用 if 语句而不是 case 语句可以解决这个问题。我不确定如何在 string_agg 函数
中执行此操作
如何实现?
编辑 1:
下面指定的答案几乎可以正常工作。但问题是逗号分隔值不是 distinct
这是更新后的 fiddle
https://dbfiddle.uk/?rdbms=postgres_14&fiddle=9647d92870e3944516172eda83a8ac6e
你可以考虑把你的case
拆分成单独的,用数组来收集。然后可以用array_to_string
格式化:
WITH notes AS (
SELECT 891090 Order_ID, False customer_billing, false commander, true agent UNION ALL
SELECT 891091, false, true, true UNION ALL
SELECT 891091, true, true, false),
tmp as (
SELECT
n.order_id id,
array_agg(
ARRAY[
CASE WHEN n.customer_billing = TRUE THEN 'AR (Customer Billing)' END,
CASE WHEN n.commander = TRUE THEN 'AP (Commander)' END,
CASE WHEN n.agent = TRUE THEN 'AP (Agent)' END
]) AS finance_array
FROM notes n
WHERE
n.order_id = 891091 AND (n.customer_billing = TRUE or n.commander = TRUE or n.agent = TRUE)
GROUP BY ORDER_ID )
select id, array_to_string(array(select distinct e from unnest(finance_array) as a(e)), ', ')
from tmp;
这里是db_fiddle.
查询如下
WITH notes AS (
SELECT 891090 Order_ID, False customer_billing, false commander, true agent
UNION ALL
SELECT 891091, false, true, true
UNION ALL
SELECT 891091, true, false, false)
SELECT
n.order_id,
string_Agg(distinct CASE
WHEN n.customer_billing = TRUE THEN 'AR (Customer Billing)'
WHEN n.commander = TRUE THEN 'AP (Commander)'
WHEN n.agent = TRUE THEN 'AP (Agent)'
ELSE NULL
END,', ') AS finance
FROM notes n
WHERE
n.order_id = 891091 AND (n.customer_billing = TRUE or n.commander = TRUE or n.agent = TRUE)
GROUP BY ORDER_ID
如您所见,有两条记录 order_id 为 891091.
- 第一个 891091 条记录
commander
和agent
设置为真 - 第二个 891091 记录已
customer_billing
设置为 true
由于使用了switch case,所以只考虑第一个真值和returnscommander
,不考虑agent
.
所以输出变成
order_id finance
891091 AP (Commander), AR (Customer Billing)
我需要考虑记录中的所有真实值,以便输出变为
order_id finance
891091 AP (Commander), AP (Agent), AR (Customer Billing)
我最初的想法是使用 if 语句而不是 case 语句可以解决这个问题。我不确定如何在 string_agg 函数
中执行此操作如何实现?
编辑 1:
下面指定的答案几乎可以正常工作。但问题是逗号分隔值不是 distinct
这是更新后的 fiddle https://dbfiddle.uk/?rdbms=postgres_14&fiddle=9647d92870e3944516172eda83a8ac6e
你可以考虑把你的case
拆分成单独的,用数组来收集。然后可以用array_to_string
格式化:
WITH notes AS (
SELECT 891090 Order_ID, False customer_billing, false commander, true agent UNION ALL
SELECT 891091, false, true, true UNION ALL
SELECT 891091, true, true, false),
tmp as (
SELECT
n.order_id id,
array_agg(
ARRAY[
CASE WHEN n.customer_billing = TRUE THEN 'AR (Customer Billing)' END,
CASE WHEN n.commander = TRUE THEN 'AP (Commander)' END,
CASE WHEN n.agent = TRUE THEN 'AP (Agent)' END
]) AS finance_array
FROM notes n
WHERE
n.order_id = 891091 AND (n.customer_billing = TRUE or n.commander = TRUE or n.agent = TRUE)
GROUP BY ORDER_ID )
select id, array_to_string(array(select distinct e from unnest(finance_array) as a(e)), ', ')
from tmp;
这里是db_fiddle.