我在表格中有以下值:
表水果
id | name | price
-----------------------------------------
1 | 'APPLE BANANA ORANGE' | 12.00
2 | 'BANANA ORANGE APPLE' | 4.00
3 | 'ORANGE APPLE BANANA' | 10.00
4 | 'LEMON APPLE BANANA ORANGE' | 7.00
5 | 'APPLE LEMON BANANA ORANGE' | 8.00
我想选择3个第一行的所有值,而我所拥有的只是包含' APPLE BANANA ORANGE'
的文字示例
SELECT *
FROM fruits
WHERE name IN
('APPLE BANANA ORANGE','BANANA ORANGE APPLE','ORANGE APPLE BANANA')
问题在于,这些价值来自另一张表,我正在寻找一种方法来生成可能值的不同组合
也许使用功能:
SELECT *
FROM fruits f
INNER JOIN order o ON o.name IN some_function(f.name)
也许使用一些正则表达式:
SELECT *
FROM fruits f
INNER JOIN order o ON o.name ~ '(?=' || f.name || ')'
我试图使用在互联网上找到的一些使用环视的正则表达式,它们带来包含这三个单词的所有值,但包括也有更多单词的单词。喜欢&LAMON APPLE BANANA ORANGE'和' APPLE LEMON BANANA ORANGE'
另一件事是我想将这些结果分组,无论它们看起来像
SELECT sum(price)
FROM fruits f
INNER JOIN order o ON o.name ~ '(?=' || f.name || ')'
GROUP BY somefunction(name);
谢谢你的帮助
Marcel Isaac
更新
我创建了一个分割字符串内容的函数,命令单词并返回带有序词的新字符串
CREATE OR REPLACE FUNCTION order_words(txt character varying)
returns character varying as
$BODY$
DECLARE
tmp character varying;
BEGIN
SELECT string_agg(t,' ')
INTO tmp
FROM (
SELECT rstt
FROM regexp_split_to_table(txt, ' ') rstt
ORDER BY rstt) t;
RETURN tmp;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
对值执行时,它始终返回相同的字符串
select order_words('APPLE BANANA ORANGE');
order_words
---------------------
APPLE BANANA ORANGE
(1 row)
select order_words('BANANA ORANGE APPLE');
order_words
---------------------
APPLE BANANA ORANGE
(1 row)
select order_words('ORANGE APPLE BANANA');
order_words
---------------------
APPLE BANANA ORANGE
(1 row)
现在我可以编写我的代码
了SELECT order_words(name),sum(price)
FROM fruits f
INNER JOIN order o ON order_words(o.name) = order_words(f.name)
GROUP BY order_words(name);
我将测试性能
答案 0 :(得分:1)
不确定这是否比您的解决方案更快:
select f.*
from fruits f
join orders o
on string_to_array(f.name, ' ') @> string_to_array(o.name, ' ')
and cardinality(string_to_array(f.name, ' ')) = cardinality(string_to_array(o.name, ' '));
我们的想法是将两个值分成数组并检查它们是否重叠。但是因为"重叠"并不意味着所有元素都相等,我也在比较数组的长度。如果长度相等且重叠,则所有元素都相等。
表达式string_to_array(f.name, ' ')
可以编入索引,@>
运算符甚至可以使用GIN索引。