PostgreSQL 中数组搜索的替代解决方案
Alternative solutions to an array search in PostgreSQL
我不确定我的数据库设计是否适用于这种棘手的情况,我还寻求帮助,查询结果如何。
我计划使用以下内容进行查询 table:
search_array | value | id
-----------------------+-------+----
{XYa,YZb,WQb} | b | 1
{XYa,YZb,WQb,RSc,QZa} | a | 2
{XYc,YZa} | c | 3
{XYb} | a | 4
{RSa} | c | 5
search_array 中有 5 个主要元素:XY、YZ、WQ、RS、QZ 和 3 个值:a、b、c 与每个元素相关联。
每行也有一个值:a、b 或 c。
我的目标是在这个意义上找到适合特定行的所有行:在 首先 应该检查它们的 [=43 中是否有任何相同的主要元素=]s(示例中黄色标记)。
例如:
行 ID 4 和行 ID 5 不匹配,因为 XY != RS.
行 id 1、2 和 3 将匹配两次,因为它们都具有 XY 和 YZ。
行 id 1 和 2 甚至会匹配三次,因为它们也有共同的 WQ。
和second:如果有一个Main Element匹配,如果Main Elements后面的小写字母适合另一行的值,它应该是'crosschecked'。
例如:table 中行 ID 1 的唯一匹配项是行 ID 4,因为它们都在元素匹配两行的每个值之后搜索 XY 和小写字母。
另一个匹配项是带有 RS 的 ROW id 2 和 5,搜索 c 到值 c 并搜索 a 到值 a(绿色和橙色标记)。
我的想法是使用字符串的 RIGHT 和 LEFT 命令将查询中的 search_array 元素分成两部分。但是我不知道如何为这个搜索组合子查询。
或者更快的完整其他解决方案?就像将搜索数组拆分为另一个 table,其中列 'foregin key' 到 maintable、'main element' 和 'searched_value'。我不确定这是否是最好的解决方案,因为程序会一直切换到主 table 以从 300 万行中找到两行以将它们的 searched_values 与值进行比较?
非常感谢您的回答和宝贵的时间!
您必须以规范化的方式表示数据。我将在 WITH
子句中执行此操作,但最好以这种方式开始存储数据。
WITH unravel AS (
SELECT t.id, t.value,
substr(u.val, 1, 2) AS arr_main,
substr(u.val, 3, 1) AS arr_val
FROM mytable AS t
CROSS JOIN LATERAL unnest(t.search_array) AS u(val)
)
SELECT a.id AS first_id,
a.value AS first_value,
b.id AS second_id,
b.value AS second_value,
a.arr_main AS main_element
FROM unravel AS a
JOIN unravel AS b
ON a.arr_main = b.arr_main
AND a.arr_val = b.value
AND b.arr_val = a.value;
我不确定我的数据库设计是否适用于这种棘手的情况,我还寻求帮助,查询结果如何。
我计划使用以下内容进行查询 table:
search_array | value | id
-----------------------+-------+----
{XYa,YZb,WQb} | b | 1
{XYa,YZb,WQb,RSc,QZa} | a | 2
{XYc,YZa} | c | 3
{XYb} | a | 4
{RSa} | c | 5
search_array 中有 5 个主要元素:XY、YZ、WQ、RS、QZ 和 3 个值:a、b、c 与每个元素相关联。 每行也有一个值:a、b 或 c。
我的目标是在这个意义上找到适合特定行的所有行:在 首先 应该检查它们的 [=43 中是否有任何相同的主要元素=]s(示例中黄色标记)。
例如:
行 ID 4 和行 ID 5 不匹配,因为 XY != RS.
行 id 1、2 和 3 将匹配两次,因为它们都具有 XY 和 YZ。
行 id 1 和 2 甚至会匹配三次,因为它们也有共同的 WQ。
和second:如果有一个Main Element匹配,如果Main Elements后面的小写字母适合另一行的值,它应该是'crosschecked'。
例如:table 中行 ID 1 的唯一匹配项是行 ID 4,因为它们都在元素匹配两行的每个值之后搜索 XY 和小写字母。 另一个匹配项是带有 RS 的 ROW id 2 和 5,搜索 c 到值 c 并搜索 a 到值 a(绿色和橙色标记)。
我的想法是使用字符串的 RIGHT 和 LEFT 命令将查询中的 search_array 元素分成两部分。但是我不知道如何为这个搜索组合子查询。
或者更快的完整其他解决方案?就像将搜索数组拆分为另一个 table,其中列 'foregin key' 到 maintable、'main element' 和 'searched_value'。我不确定这是否是最好的解决方案,因为程序会一直切换到主 table 以从 300 万行中找到两行以将它们的 searched_values 与值进行比较?
非常感谢您的回答和宝贵的时间!
您必须以规范化的方式表示数据。我将在 WITH
子句中执行此操作,但最好以这种方式开始存储数据。
WITH unravel AS (
SELECT t.id, t.value,
substr(u.val, 1, 2) AS arr_main,
substr(u.val, 3, 1) AS arr_val
FROM mytable AS t
CROSS JOIN LATERAL unnest(t.search_array) AS u(val)
)
SELECT a.id AS first_id,
a.value AS first_value,
b.id AS second_id,
b.value AS second_value,
a.arr_main AS main_element
FROM unravel AS a
JOIN unravel AS b
ON a.arr_main = b.arr_main
AND a.arr_val = b.value
AND b.arr_val = a.value;