You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLite跨环境对比应用版本:找出DEV版本低于STAGE的应用

Compare SQLite App Versions Across Environments

Got it, let's solve this problem of finding apps where the DEV version is lower than the STAGE version. The main hurdle here is correctly comparing version numbers—since they're string-formatted with multiple segments, standard string comparison won't cut it (think about how '1.10' would incorrectly be seen as smaller than '1.9').

Step 1: Pair Up DEV and STAGE Data

First, we need to match each app that exists in both environments. This is straightforward with an INNER JOIN:

SELECT 
    d.APP_NAME,
    d.APP_VERSION AS dev_version,
    s.APP_VERSION AS stage_version
FROM apps d
INNER JOIN apps s 
    ON d.APP_NAME = s.APP_NAME
    AND d.ENV = 'DEV'
    AND s.ENV = 'STAGE'

This gives us a list of apps present in both environments, along with their respective versions. Now we need to filter this list to only include rows where dev_version < stage_version.

Method 1: Pure SQL Version Comparison (No Custom Functions)

Since SQLite doesn't have a built-in version comparison function, we can use a recursive CTE to split version strings into numeric segments, then compare each segment one by one. This handles cases where versions have different lengths (like 1.0 vs 1.0.3.4).

Here's the full query:

WITH RECURSIVE split_versions(APP_NAME, env, version_part, remaining_version, part_num) AS (
    -- Initialize: extract the first version segment
    SELECT 
        APP_NAME,
        ENV,
        CAST(SUBSTR(APP_VERSION, 1, INSTR(APP_VERSION || '.', '.') - 1) AS INTEGER),
        SUBSTR(APP_VERSION, INSTR(APP_VERSION || '.', '.') + 1),
        1
    FROM apps
    WHERE ENV IN ('DEV', 'STAGE')
    
    UNION ALL
    
    -- Recursively split remaining segments
    SELECT 
        APP_NAME,
        env,
        CAST(SUBSTR(remaining_version, 1, INSTR(remaining_version || '.', '.') - 1) AS INTEGER),
        SUBSTR(remaining_version, INSTR(remaining_version || '.', '.') + 1),
        part_num + 1
    FROM split_versions
    WHERE remaining_version != ''
),
version_comparison AS (
    SELECT 
        d.APP_NAME,
        d.version_part AS dev_part,
        s.version_part AS stage_part,
        d.part_num,
        CASE 
            WHEN d.version_part < s.version_part THEN 'LESS'
            WHEN d.version_part > s.version_part THEN 'GREATER'
            ELSE 'EQUAL'
        END AS comparison
    FROM split_versions d
    INNER JOIN split_versions s 
        ON d.APP_NAME = s.APP_NAME
        AND d.part_num = s.part_num
        AND d.env = 'DEV'
        AND s.env = 'STAGE'
)
SELECT DISTINCT APP_NAME
FROM version_comparison
WHERE 
    -- Case 1: First differing segment shows DEV version is smaller
    (comparison = 'LESS' AND part_num = (
        SELECT MIN(part_num) 
        FROM version_comparison vc 
        WHERE vc.APP_NAME = version_comparison.APP_NAME 
          AND vc.comparison != 'EQUAL'
    ))
    -- Case 2: All matching segments are equal, but DEV has fewer segments (e.g., 1.0 vs 1.0.1)
    OR (
        (SELECT COUNT(*) FROM split_versions d WHERE d.APP_NAME = version_comparison.APP_NAME AND d.env = 'DEV') < 
        (SELECT COUNT(*) FROM split_versions s WHERE s.APP_NAME = version_comparison.APP_NAME AND s.env = 'STAGE')
        AND NOT EXISTS (
            SELECT 1 
            FROM version_comparison vc 
            WHERE vc.APP_NAME = version_comparison.APP_NAME 
              AND vc.comparison = 'GREATER'
        )
    )

Method 2: Custom Function (Simpler, if allowed)

If you can use custom functions (e.g., with Python in pysqlite), you can create a helper function to compare versions directly. This makes the query much cleaner.

First, create the function:

CREATE FUNCTION compare_versions(a TEXT, b TEXT) RETURNS INTEGER AS $$
    parts_a = list(map(int, a.split('.')))
    parts_b = list(map(int, b.split('.')))
    max_len = max(len(parts_a), len(parts_b))
    -- Pad shorter version with zeros to match length
    parts_a += [0] * (max_len - len(parts_a))
    parts_b += [0] * (max_len - len(parts_b))
    for x, y in zip(parts_a, parts_b):
        if x < y:
            return -1
        elif x > y:
            return 1
    return 0
$$ LANGUAGE python;

Then use it in your query:

SELECT 
    d.APP_NAME
FROM apps d
INNER JOIN apps s 
    ON d.APP_NAME = s.APP_NAME
    AND d.ENV = 'DEV'
    AND s.ENV = 'STAGE'
WHERE compare_versions(d.APP_VERSION, s.APP_VERSION) = -1;

Result for Your Sample Data

Using your sample data (assuming the typo Applictaion_1/Applictaion_4 is a misspelling of Application_1/Application_4), the query will return:

Application_3

Because DEV's 1.0 is lower than STAGE's 1.0.3.4, while DEV's 1.2 for Application_1 is higher than STAGE's 0.2.3.

内容的提问来源于stack exchange,提问作者Rahul Trivedi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:08:20