sqlite表由以下属性组成:
|Versions (TEXT)|
| "2.73.8" |
| "3.6.4 " |
| "3.9.11" |
以此类推。
我想从查询中给定的两个版本之间的表中检索所有版本。例如:在2.9.10和3.7.10之间。
我找不到任何sqlite函数直接查询此函数。我使用Substring(SUBSTR)进行拆分以获取各个数字,然后可以将这些数字与表中存在的数字进行比较。我这样做很成功,但是我可以找到一种查询方法来检索两个版本集之间的所有版本。
create table prod(version varchar);
insert into prod values('2.7.5');
insert into prod values('2.7.4');
insert into prod values('2.0.0');
insert into prod values('22.73.55');
insert into prod values('22.17.54');
insert into prod values('22.10.06');
insert into prod values('3.7.5');
insert into prod values('3.4.5');
insert into prod values('3.7.6');
查询以获取低于或等于以下所有版本:“ 3.50.6”(使用嵌套的“ case when”):
SELECT * from prod
Where version IN ( SELECT
CASE WHEN (CAST(substr(version,0,instr(version,'.')) as integer)=3)
THEN
CASE WHEN (cast(SUBSTR(SUBSTR(version, INSTR(version, '.')),1,INSTR(SUBSTR(version, INSTR(version, '.') + 1), '.') - 1) as float)< 0.50 )
THEN
version
ELSE
CASE WHEN (cast(SUBSTR(SUBSTR(version, INSTR(version, '.')),1,INSTR(SUBSTR(version, INSTR(version, '.') + 1), '.') - 1) as float)=0.50)
THEN
CASE WHEN (CAST(replace(version, rtrim(version, replace(version, '.', '')), '')AS INTEGER)<=6)
THEN version
END END END END FROM prod);
请为我提供一种查询以检索表中两组版本之间的所有版本的方法。
答案 0 :(得分:0)
我相信以下内容可以满足您的要求:-
WITH
/* SELECTION parameters */
parm(p1,p2) AS (SELECT '3.4.5', '22.10.6' /*<<<<<<<<<<<<< Versions to check against lower first*/),
/* Parse 1, 1st value of each and the rest for parse2 */
pv1(parmv1,rest4p2,parm2v1,rest4p22) AS (
SELECT
CAST(substr(p1,1,instr(p1,'.')-1) AS INTEGER),
substr(p1,instr(p1,'.')+1),
CAST(substr(p2,1,instr(p2,'.')-1) AS INTEGER),
substr(p2,instr(p2,'.')+1)
FROM parm
),
/* Parse 2 extra 2 values retrieved for each parameter */
pv2(parmv2,parmv3,parm2v2,parm2v3) AS (
SELECT
CAST(substr(rest4p2,1,instr(rest4p2,'.')-1) AS INTEGER),
CAST(substr(rest4p2,instr(rest4p2,'.')+1) AS INTEGER),
CAST(substr(rest4p22,1,instr(rest4p22,'.')-1) AS INTEGER),
CAST(substr(rest4p22,instr(rest4p22,'.')+1) AS INTEGER)
FROM pv1),
/* calculate the lower and upper values to be checked against for the BETWEEN clause */
finalp(lower,higher) AS (
SELECT
(parmv1 * 1000 * 1000) + (SELECT (parmv2 * 1000) + parmv3 FROM pv2),
(parm2v1 * 1000 * 1000) + (SELECT (parm2v2 * 1000) + parm2v3 FROM pv2)
FROM pv1),
/* Parse 1 for the actual data gets the 1st part of the version and the rest of the version */
v1(v1rowid,vpart1,rest4v2) AS (SELECT rowid, CAST(substr(version,1,instr(version,'.')-1) AS INTEGER),substr(version,instr(version,'.')+1) FROM prod),
/* Parse 2 for the actual data gets the 2nd and third parts */
v2(v2rowid,vpart2,vpart3) AS (SELECT v1rowid, CAST(substr(rest4v2,1,instr(rest4v2,'.')+1) AS INTEGER),CAST(substr(rest4v2,instr(rest4v2,'.')+1) AS INTEGER) FROM v1)
SELECT version
FROM v1
JOIN v2 ON v1rowid = v2rowid /* join the 2nd and third parts with the 1st */
JOIN prod ON prod.rowid = v1rowid /* also join the original data for the original version */
JOIN finalp ON 1 = 1 /* joint the upper and lower values */
WHERE
(vpart1 * 1000 * 1000) + (vpart2 * 1000) + vpart3 /* do the same calculation used for the upper and lower parameters */
BETWEEN lower AND higher
;
以上结果为:-
并使用:-
.... (SELECT '3.4.5', '22.10.06' /*<<<<<<<<<<<<< Versions to check against lower first*/) ...
以及:-
.... (SELECT '3.4.5', '22.10.6' /*<<<<<<<<<<<<< Versions to check against lower first*/) ....
- .6
而不是 .06
(即忽略前导0)
结果:-
答案 1 :(得分:0)
我假设版本值的3个部分中的每个部分最多3个数字。
将版本值转换为数字以使其具有可比性的最简单方法是:将第一部分乘以1000000,第二部分乘以1000,然后将其加3d部分。
在代码中:
1000000 * replace(version, '.', 'x') +
1000 * replace(substr(version, instr(version, '.') + 1), '.', 'x') +
replace(version, '.', '000') % 1000 number
如果执行:
select
version,
1000000 * replace(version, '.', 'x') +
1000 * replace(substr(version, instr(version, '.') + 1), '.', 'x') +
replace(version, '.', '000') % 1000 numericversion
from prod
您得到:
| version | numericversion |
| -------- | -------------- |
| 2.7.5 | 2007005 |
| 2.7.4 | 2007004 |
| 2.0.0 | 2000000 |
| 22.73.55 | 22073055 |
| 22.17.54 | 22017054 |
| 22.10.06 | 22010006 |
| 3.7.5 | 3007005 |
| 3.4.5 | 3004005 |
| 3.7.6 | 3007006 |
因此,要获取2.9.10和3.7.10之间的所有版本,请执行以下操作:
with
cte1 as (
select
1000000 * replace('2.9.10', '.', 'x') +
1000 * replace(substr('2.9.10', instr('2.9.10', '.') + 1), '.', 'x') +
replace('2.9.10', '.', '000') % 1000 numericversion
),
cte2 as (
select
1000000 * replace('3.7.10', '.', 'x') +
1000 * replace(substr('3.7.10', instr('3.7.10', '.') + 1), '.', 'x') +
replace('3.7.10', '.', '000') % 1000 numericversion
),
versions as (
select
version,
1000000 * replace(version, '.', 'x') +
1000 * replace(substr(version, instr(version, '.') + 1), '.', 'x') +
replace(version, '.', '000') % 1000 numericversion
from prod
)
select version from versions
where numericversion between
(select numericversion from cte1) and (select numericversion from cte2)
第一个CTE返回数值2.9.10
,第二个CTE返回数值3.7.10
,而3d返回表中所有版本的数值。
最后,查询会比较数字版本。
请参见demo。
结果:
| version |
| ------- |
| 3.7.5 |
| 3.4.5 |
| 3.7.6 |
或者没有CTE,可以将2个版本硬编码为数字:
select version from prod
where
1000000 * replace(version, '.', 'x') +
1000 * replace(substr(version, instr(version, '.') + 1), '.', 'x') +
replace(version, '.', '000') % 1000
between 2009010 and 3007010
请参见demo。
或者:
select version from prod
where
1000000 * replace(version, '.', 'x') +
1000 * replace(substr(version, instr(version, '.') + 1), '.', 'x') +
replace(version, '.', '000') % 1000
between
1000000 * replace('2.9.10', '.', 'x') +
1000 * replace(substr('2.9.10', instr('2.9.10', '.') + 1), '.', 'x') +
replace('2.9.10', '.', '000') % 1000
and
1000000 * replace('3.7.10', '.', 'x') +
1000 * replace(substr('3.7.10', instr('3.7.10', '.') + 1), '.', 'x') +
replace('3.7.10', '.', '000') % 1000
请参见demo。