Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQLITE查询-检索两个版本之间的所有版本?_Sql_Python 3.x_Sqlite_Version - Fatal编程技术网

SQLITE查询-检索两个版本之间的所有版本?

SQLITE查询-检索两个版本之间的所有版本?,sql,python-3.x,sqlite,version,Sql,Python 3.x,Sqlite,Version,sqlite表由以下属性组成: |Versions (TEXT)| | "2.73.8" | | "3.6.4 " | | "3.9.11" | 等等 我想从表中检索查询中给定的两个版本之间的所有版本。例如:在版本-2.9.10和3.7.10之间 我找不到任何sqlite函数来直接查询它。我使用Substring SUBSTR进行拆分,得到各个数字,然后可以将这些数字与表中的数字进行比较。我成功地做到了这一点,但我可以找到一种查询方法来检索两个版本集之间的

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的所有版本:


请为我提供一种查询方法,以便在两组版本之间检索表中的所有版本。

我相信以下内容可以满足您的要求:-

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

结果:-

这也检查了边界命中,即选择了3.4.5和20.10.06。
我假设版本值的3个部分中的每一部分最多为3位。 将版本值转换为数字以使其具有可比性的最简单方法是:将第一部分乘以1000000,第二部分乘以1000,然后将它们加上3d部分。 代码:

如果您执行:

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,第三个CTE返回表中所有版本的数值。 最后,查询比较数字版本。 看。 结果:

或不带CTEs,将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
看。 或:


请参阅。

,非常感谢。在使用python库sqlite时,我应该如何在c.execute中包含此查询。另外,如何将两个版本的输入作为此查询的变量?不幸的是,python2.7附带的sqlite版本不支持with,并且由于其他依赖关系,我必须坚持使用该版本。因此,您可以为您的解决方案提供一个不使用的替代方案。感谢您的努力。最后一个查询没有使用with.true,但我希望在查询中以版本号的形式传递变量,以便使查询能够针对给定的任何版本集运行。在使用python库sqlite时,我应该如何将此查询包含在c.execute中。另外,如何将两个版本的输入作为此查询的变量?不幸的是,python2.7附带的sqlite版本不支持with,并且由于其他依赖关系,我必须坚持使用该版本。因此,您可以为您的解决方案提供一个不使用的替代方案。我感谢你的努力。
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)
| version |
| ------- |
| 3.7.5   |
| 3.4.5   |
| 3.7.6   |
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
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