gue*_*tli 5 postgresql range-types
如何从较大的范围中减去较小的子范围?
123456789
567
Run Code Online (Sandbox Code Playgroud)
结果:
1234 89
Run Code Online (Sandbox Code Playgroud)
查询语句:
select '[1,9]'::int4range - '[5,7]'::int4range;
ERROR: result of range difference would not be contiguous
Run Code Online (Sandbox Code Playgroud)
结果不适合 int4range,因为它不连续。
如何将结果作为一组 int4ranges?
解决方案可能是这样的
\n\nCREATE TABLE test_ranges (\n big_range int4range,\n small_range int4range,\n test_case text\n);\n\nINSERT INTO test_ranges\nVALUES \n (\'[1,9]\'::int4range, \'[5,7]\'::int4range, \'smaller range splits bigger into two\'),\n (\'[1,9]\'::int4range, \'[1,9]\'::int4range, \'smaller is the same as bigger\'),\n (\'[1,9]\'::int4range, \'[0,9]\'::int4range, \'smaller is bigger\'),\n (\'[1,9]\'::int4range, \'[1,4]\'::int4range, \'smaller removes the left part of bigger (same effect expected on the right side)\'),\n (\'[1,9]\'::int4range, \'empty\'::int4range, \'smaller is empty\'),\n (\'empty\'::int4range, \'[5,7]\'::int4range, \'bigger is empty\');\n\n/* please note that you have to reorganize the query a bit \n in order to get the \'halves\' as a set */\n\nSELECT \n CASE WHEN isempty(small_range)\n THEN big_range\n ELSE big_range - int4range(lower(small_range), upper(big_range)) \n END AS first_half,\n big_range - int4range(lower(big_range), upper(small_range)) AS second_half, \n test_case\nFROM test_ranges;\n
Run Code Online (Sandbox Code Playgroud)\n\n注意
\n\ntest=# SELECT \'[1,5)\'::int4range = \'[1,4]\'::int4range;\n ?column? \n\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80\n t\n
Run Code Online (Sandbox Code Playgroud)\n\n有一个小的SQLFiddle可以在工作中展示这一点。感谢 ypercube 让我注意到原始查询未涵盖的一个极端情况。
\n