我有一个包含6个联合的查询,用于获取6个不同级别的数据,然后对其进行排序.

更新的数据库字段:https://dbfiddle.uk/zNH3Xjog

以下是基本数据:

SHELFLOCID PARENTSHELFLOCID DEPTH PICKSORTVALUE
55 0 1 1
33 55 2 1
88 55 2 2
11 0 1 1
77 11 2 1

我需要使用该查询来使用排序后的订单更新数据库中的另一个字段,因此我想返回一个计数器,并使用该计数器和ID字段进行更新.

以下是查询:

SELECT
    LEVEL1_DATA.PICKSORTVALUE AS LEVEL1SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL2SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL3SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL4SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL5SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL6SORT,
    LEVEL1_DATA.SHELFLOCID
FROM
    INVENTORYSHELFLOCATIONS LEVEL1_DATA
WHERE
    LEVEL1_DATA.DEPTH = 1
    AND LEVEL1_DATA.LOCATIONID = 24541891
  
UNION

SELECT
    LEVEL2_LEVEL1.PICKSORTVALUE AS LEVEL1SORT,
    LEVEL2_DATA.PICKSORTVALUE AS LEVEL2SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL3SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL4SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL5SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL6SORT,
    LEVEL2_DATA.SHELFLOCID
FROM
    INVENTORYSHELFLOCATIONS LEVEL2_DATA
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL2_LEVEL1 ON LEVEL2_LEVEL1.SHELFLOCID = LEVEL2_DATA.PARENTSHELFLOCID
WHERE
    LEVEL2_DATA.DEPTH = 2
    AND LEVEL2_DATA.LOCATIONID = 24541891

UNION

SELECT
    LEVEL3_LEVEL1.PICKSORTVALUE AS LEVEL1SORT,
    LEVEL3_LEVEL2.PICKSORTVALUE AS LEVEL2SORT,
    LEVEL3_DATA.PICKSORTVALUE AS LEVEL3SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL4SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL5SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL6SORT,
    LEVEL3_DATA.SHELFLOCID
FROM
    INVENTORYSHELFLOCATIONS LEVEL3_DATA
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL3_LEVEL2 ON LEVEL3_LEVEL2.SHELFLOCID = LEVEL3_DATA.PARENTSHELFLOCID
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL3_LEVEL1 ON LEVEL3_LEVEL1.SHELFLOCID = LEVEL3_LEVEL2.PARENTSHELFLOCID
WHERE
    LEVEL3_DATA.DEPTH = 3
    AND LEVEL3_DATA.LOCATIONID = 24541891

UNION

SELECT
    LEVEL4_LEVEL1.PICKSORTVALUE AS LEVEL1SORT,
    LEVEL4_LEVEL2.PICKSORTVALUE AS LEVEL2SORT,
    LEVEL4_LEVEL3.PICKSORTVALUE AS LEVEL3SORT,
    LEVEL4_DATA.PICKSORTVALUE AS LEVEL4SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL5SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL6SORT,
    LEVEL4_DATA.SHELFLOCID
FROM
    INVENTORYSHELFLOCATIONS LEVEL4_DATA
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL4_LEVEL3 ON LEVEL4_LEVEL3.SHELFLOCID = LEVEL4_DATA.PARENTSHELFLOCID
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL4_LEVEL2 ON LEVEL4_LEVEL2.SHELFLOCID = LEVEL4_LEVEL3.PARENTSHELFLOCID
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL4_LEVEL1 ON LEVEL4_LEVEL1.SHELFLOCID = LEVEL4_LEVEL2.PARENTSHELFLOCID
WHERE
    LEVEL4_DATA.DEPTH = 4
    AND LEVEL4_DATA.LOCATIONID = 24541891

UNION

SELECT
    LEVEL5_LEVEL1.PICKSORTVALUE AS LEVEL1SORT,
    LEVEL5_LEVEL2.PICKSORTVALUE AS LEVEL2SORT,
    LEVEL5_LEVEL3.PICKSORTVALUE AS LEVEL3SORT,
    LEVEL5_LEVEL4.PICKSORTVALUE AS LEVEL4SORT,
    LEVEL5_DATA.PICKSORTVALUE AS LEVEL5SORT,
    CAST(0 AS NUMERIC(10,0)) AS LEVEL6SORT,
    LEVEL5_DATA.SHELFLOCID
FROM
    INVENTORYSHELFLOCATIONS LEVEL5_DATA
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL5_LEVEL4 ON LEVEL5_LEVEL4.SHELFLOCID = LEVEL5_DATA.PARENTSHELFLOCID
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL5_LEVEL3 ON LEVEL5_LEVEL3.SHELFLOCID = LEVEL5_LEVEL4.PARENTSHELFLOCID
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL5_LEVEL2 ON LEVEL5_LEVEL2.SHELFLOCID = LEVEL5_LEVEL3.PARENTSHELFLOCID
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL5_LEVEL1 ON LEVEL5_LEVEL1.SHELFLOCID = LEVEL5_LEVEL2.PARENTSHELFLOCID
WHERE
    LEVEL5_DATA.DEPTH = 5
    AND LEVEL5_DATA.LOCATIONID = 24541891

UNION

SELECT
    LEVEL6_LEVEL1.PICKSORTVALUE AS LEVEL1SORT,
    LEVEL6_LEVEL2.PICKSORTVALUE AS LEVEL2SORT,
    LEVEL6_LEVEL3.PICKSORTVALUE AS LEVEL3SORT,
    LEVEL6_LEVEL4.PICKSORTVALUE AS LEVEL4SORT,
    LEVEL6_LEVEL5.PICKSORTVALUE AS LEVEL5SORT,
    LEVEL6_DATA.PICKSORTVALUE AS LEVEL6SORT,
    LEVEL6_DATA.SHELFLOCID
FROM
    INVENTORYSHELFLOCATIONS LEVEL6_DATA
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL6_LEVEL5 ON LEVEL6_LEVEL5.SHELFLOCID = LEVEL6_DATA.PARENTSHELFLOCID
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL6_LEVEL4 ON LEVEL6_LEVEL4.SHELFLOCID = LEVEL6_LEVEL5.PARENTSHELFLOCID
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL6_LEVEL3 ON LEVEL6_LEVEL3.SHELFLOCID = LEVEL6_LEVEL4.PARENTSHELFLOCID
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL6_LEVEL2 ON LEVEL6_LEVEL2.SHELFLOCID = LEVEL6_LEVEL3.PARENTSHELFLOCID
LEFT JOIN
    INVENTORYSHELFLOCATIONS LEVEL6_LEVEL1 ON LEVEL6_LEVEL1.SHELFLOCID = LEVEL6_LEVEL2.PARENTSHELFLOCID
WHERE
    LEVEL6_DATA.DEPTH = 6
    AND LEVEL6_DATA.LOCATIONID = 24541891
ORDER BY
    1, 2, 3, 4, 5, 6

这将返回一个对前6列进行排序的结果集,这些列是在程序本身的保存操作中预先排序的值(使用PICKSORTVALUE和DISPLAYORDER).

结果如下所示:

LEVEL1SORT LEVEL2SORT LEVEL3SORT LEVEL4SORT LEVEL5SORT LEVEL6SORT SHELFLOCID
1 0 0 0 0 0 55
1 1 0 0 0 0 33
1 2 0 0 0 0 88
2 0 0 0 0 0 11
2 1 0 0 0 0 55

然后,我希望在更新查询中使用行计数器和SHELFLOCID字段:

UPDATE INVENTORYSHELFLOCATIONS 
SET PICKORDER = 1, 2, 3, 4,etc
WHERE SHELFLOCID = 55, 33, 88, 11,etc

我可以逐个遍历结果并更新记录,这需要大约4秒的时间来处理,但我希望在数据库级别做一些事情.

它必须在单个查询中完成,并且不能在查询中包含多个部分.

更新后的数据库将如下所示:

SHELFLOCID PICKORDER
55 1
33 2
88 3
11 4
77 5

这是可以做到的吗?

推荐答案

您可以使用带有ROW_NUMBER()函数的公用表表达式(CTE)来生成排序数据的行号,然后使用该信息来更新PICKORDER字段.下面是SQL查询

WITH SortedData AS (
    SELECT
        SHELFLOCID,
        ROW_NUMBER() OVER (
            ORDER BY LEVEL1SORT, LEVEL2SORT, LEVEL3SORT, LEVEL4SORT, LEVEL5SORT, LEVEL6SORT
        ) AS RowNum
    FROM (
        -- Your existing query goes here
        SELECT
            LEVEL1_DATA.PICKSORTVALUE AS LEVEL1SORT,
            CAST(0 AS NUMERIC(10,0)) AS LEVEL2SORT,
            CAST(0 AS NUMERIC(10,0)) AS LEVEL3SORT,
            CAST(0 AS NUMERIC(10,0)) AS LEVEL4SORT,
            CAST(0 AS NUMERIC(10,0)) AS LEVEL5SORT,
            CAST(0 AS NUMERIC(10,0)) AS LEVEL6SORT,
            LEVEL1_DATA.SHELFLOCID
        FROM
            INVENTORYSHELFLOCATIONS LEVEL1_DATA
        WHERE
            LEVEL1_DATA.DEPTH = 1
            AND LEVEL1_DATA.LOCATIONID = 24541891

        UNION

        -- Your other UNION queries go here
        -- (Levels 2, 3, 4, 5, 6)
    ) AS CombinedData
)
UPDATE INVENTORYSHELFLOCATIONS AS ISL
SET PICKORDER = SD.RowNum
FROM SortedData AS SD
WHERE ISL.SHELFLOCID = SD.SHELFLOCID;

Sql相关问答推荐

表名数组

基于时间的SQL聚合

如果开始期间不存在PostgresSql回填数据

PostgreSQL中的合并命令是原子的,还是需要一些类似于SQL Server版本的内容?

每组显示一行(表1中的分组值),表2中的不同列表用逗号分隔

防止ActiveRecord迁移在db/structure.sql中进行巨大更改

在迁移到.NET8后,使用Array.Containers的F#查询表达式失败

以一致的价值获得独特的价值

用VB.NET在Dapper中实现MS Access数据库顺序透视

使用同一个表,为什么IN、NOT IN、NOT EXISTS和EXISTS有不同的输出?

显示十进制列,但尽可能显示为整数

配置单元查询失败:无法识别';附近的输入;LEFT'';(select子句中的';';col'

特殊条件计算小计

获取多个开始-结束时间戳集之间经过的时间

使用 SQL 计算一年中任意 3 个月期间的总成本

使用SQLAlchemy和Postgres数据库创建新行时,为什么我的创建日期比更新日期晚?

如何通过CROSS APPLY获取多级嵌套JSON属性的值?

PlSql 陷入死循环

Athena:从字符串birth_dt列计算年龄

SQL:获取连接表的第一个项目