假设我有一个事件表:
id bigint NOT NULL PRIMARY KEY,
tenant_id CHARACTER VARYING(50) NOT NULL,
name CHARACTER VARYING(100) NOT NULL,
code CHARACTER VARYING(50) NOT NULL,
UNIQUE (code, tenant_id)
我想检索事件列表,但有些复杂。 一些示例数据:
tenant_id | 姓名 | 代码 |
---|---|---|
美国 | 用户注册 | 用户注册 |
加拿大 | 用户注册 | 用户注册 |
默认 | 用户注册 | 用户注册 |
加拿大 | 用户帐户删除 | 用户帐户删除 |
西班牙 | 用户帐户删除 | 用户帐户删除 |
如您所见,相同的事件代码可以出现在多个租户中。对于一些特殊事件,他们也会在一个名为“default”的特殊租户中有一个条目。
我希望我的搜索检索事件表中的所有列(为简洁起见省略了一些列),由 tenant_id 过滤,但我只想要事件代码的不同值,并且如果请求中尚未存在,则希望包括“默认”tenant_id房客
例如,如果我使用“加拿大”的 tenant_id 请求搜索,我希望结果为:
tenant_id | 姓名 | 代码 |
---|---|---|
加拿大 | 用户注册 | 用户注册 |
加拿大 | 用户帐户删除 | 用户帐户删除 |
请注意,用户注册不应出现两次,即使它在加拿大和默认租户中都存在。
然后如果我想用“西班牙”的tenant_id搜索,我希望结果是:
tenant_id | 姓名 | 代码 |
---|---|---|
默认 | 用户注册 | 用户注册 |
西班牙 | 用户帐户删除 | 用户帐户删除 |
请注意,因为用户注册在西班牙租户中不存在,但在默认租户中存在,所以它会出现。
如果我搜索随机租户,我希望默认租户中的所有事件都存在:
tenant_id | 姓名 | 代码 |
---|---|---|
默认 | 用户注册 | 用户注册 |
我不太熟悉SQL,但尝试了一些基本的想法。为混淆道歉,我正在使用 HQL.
函数签名:
searchEvents(String tenantId);
使用地点:
SELECT new Event(e.id, e.tenantId, e.name, e.code)
FROM Event e
WHERE e.tenantId IN (:tenantId, 'default')
这可以在请求的租户或默认租户中获取事件,但如果它在指定的租户和默认租户中,则包含重复的事件代码。
使用 GROUP BY 代码:
SELECT new Event(e.id, e.tenantId, e.name, e.code)
FROM Event e
WHERE e.tenantId IN (:tenantId, 'default')
GROUP BY e.code
错误。错误:列“event0_.id”必须出现在 GROUP BY 子句中或用于聚合函数中。
This question I found seems similar,但不是获取租户列的“最大”值并按代码分组,我想要一个最大值,我定义了租户提供最大值的位置,下一个值将是“默认”租户. SQL 仅选择列上具有最大值的行
另一个选项可能是定义我自己的顺序SQL只选择列上具有自定义最大值的行但如果有更简单的东西,我不想去那个兔子洞。
您可以结合使用子查询和 UNION ALL 来获得所需的结果。子查询将为请求的租户和默认租户检索不同的事件代码,UNION ALL 将合并结果。
SELECT e.id, e.tenant_id, e.name, e.code
FROM events e
WHERE e.code IN (
SELECT DISTINCT code
FROM events
WHERE tenant_id = :tenantId
UNION ALL
SELECT DISTINCT code
FROM events
WHERE tenant_id = 'default' AND code NOT IN (
SELECT DISTINCT code
FROM events
WHERE tenant_id = :tenantId
)
)