给定以下数据库结构:
区域
id | 名称 |
---|---|
1 | 欧盟 |
2 | 美国 |
3 | SEA |
还有一个PL/pgSQL函数,定义为sendShipment((,它接受(除其他外(发送方和接收方客户ID。
这方面有一个业务约束,要求我们验证发送方和接收方是否位于同一区域,并且我们需要将此作为sendShipment((的一部分来执行。因此,在这个函数中,我们需要在客户表中查询发送方和接收方ID,并验证它们的区域ID是否相同。我们还需要对自己进行身份验证,以便后续进行进一步处理。
此查询应该有效:
WITH q AS (
SELECT
COUNT( * ) AS CountCustomers,
COUNT( DISTINCT c.Region ) AS CountDistinctRegions,
-- MIN( c.Region ) AS MinRegion
FIRST_VALUE( c.Region ) OVER ( ORDER BY c.Region ) AS MinRegion
FROM
Customers AS c
WHERE
c.CustomerId = $senderCustomerId
OR
c.CustomerId = $receiverCustomerId
)
SELECT
CASE WHEN q.CountCustomers = 2 AND q.CountDistinctRegions = 2 THEN 'OK' ELSE 'BAD' END AS "Status",
CASE WHEN q.CountDistinctRegions = 2 THEN q.MinRegion END AS SingleRegion
FROM
q
上述查询将始终返回一行,其中包含两列:
Status
和SingleRegion
。- 再一次,这是ISO SQL委员会的错,而不是PostgreSQL的错
由于您的
Region
列是UUID,您不能将其与MIN
一起使用,但我理解它应该与FIRST_VALUE( c.Region ) OVER ( ORDER BY c.Region ) AS MinRegion
一起使用。关于列:
Status
列是'OK'
或'BAD'
,这取决于您提到的那些业务约束。不过,您可能希望将其更改为bit
列,而不是文本列- 如果
CountDistinctRegions = 2
而不考虑CountCustomers
,则SingleRegion
列将为NOT NULL
(具有有效区域(,但请随意更改,以防您仍然需要该信息
NULL
的函数(,但我们可以在CTE或派生表中使用MIN
(或MAX
(和CASE WHEN COUNT()
作为等效操作GROUP BY
查询中不起作用,尽管它们非常相似,argh对于其他对简单解决方案感兴趣的人,我终于想出了(有点明显(的方法:
SELECT
r.region
FROM
customers s
INNER JOIN customers r ON
s.region = r.region
WHERE s.id = 'sender_id' and r.id = 'receiver_id';
SELECT DISTINCT最多只返回了一行,他在这方面帮了我很多忙,还发布了一个可行的解决方案。