【问题标题】:Convert CTE from Postgres to MSSQL将 CTE 从 Postgres 转换为 MSSQL
【发布时间】:2017-12-07 10:34:40
【问题描述】:

我应该从 Postgresql zu MSSQL 转换 CTE。 问题是,Postgresql-Query 使用数组。我不知道如何将它们转换为 MSSQL。

这是创建数据的完整查询:

CREATE TABLE pairs (
    from_city VARCHAR(255) NOT NULL,
    to_city VARCHAR(255) NOT NULL,
    distance INTEGER NOT NULL,
    PRIMARY KEY(from_city, to_city),
    CHECK (from_city < to_city)
);


INSERT INTO pairs
VALUES
('Bari','Bologna',672),
('Bari','Genova',944),
('Bari','Milano',881),
('Bari','Napoli',257),
('Bari','Palermo',708),
('Bologna','Genova',190),
('Bologna','Milano',200),
('Bologna','Napoli',470),
('Bologna','Palermo',730),
('Bologna','Roma',300), 
('Genova','Milano',120),
('Genova','Napoli',590),
('Genova','Palermo',790),
('Genova','Roma',400),
('Milano','Napoli',660),
('Milano','Palermo',890),
('Milano','Roma',480),
('Napoli','Palermo',310),
('Napoli','Roma',190),
('Palermo','Roma',430);


SELECT * FROM pairs;


-- Paths from Palermo to Milano...
;WITH RECURSIVE both_ways (
    from_city,
    to_city,
    distance
) /* Working Table containing all ways */
AS (
    SELECT
        from_city,
        to_city,
        distance
    FROM pairs
UNION ALL
    SELECT
        to_city AS "from_city",
        from_city AS "to_city",
        distance
    FROM pairs
),
paths (
    from_city,
    to_city,
    distance,
    path
)
AS (
    SELECT
        from_city,
        to_city,
        distance,
        ARRAY[from_city] AS "path"
    FROM both_ways b1
    WHERE b1.from_city = 'Palermo' --<<< Start Node >>>
  UNION ALL
    SELECT
        b2.from_city,
        b2.to_city,
        p.distance + b2.distance,
        p.path + b2.from_city
    FROM both_ways b2
    JOIN paths p
         ON (p.to_city = b2.from_city
             AND b2.from_city <> ALL (p.path[2:array_upper(p.path,1)]) /* Prevent re-tracing */
             AND array_upper(p.path,1) < 6)
)
SELECT
    path || to_city AS "path",
    distance
FROM paths
WHERE to_city = 'Milano'  --<<< End node >>>
AND ARRAY['Napoli','Roma','Bari'] <@ path -- <<< via... >>> - <@ means 'is contained by' 
ORDER BY distance, path 
LIMIT 5;

希望有人能帮助我,如何转换

ARRAY[from_city] AS "path"

在路径的定义中

路径中的此条件-CTE:

AND b2.from_city <> ALL (p.path[2:array_upper(p.path,1)]) /* Prevent re-tracing */
         AND array_upper(p.path,1) < 6)

使用 CTE 的 select 的这个条件:

AND ARRAY['Napoli','Roma','Bari'] <@ path -- <<< via... >>> - <@ means 'is contained by' 

【问题讨论】:

  • 问题是ARRAY,而不是 CTE。 SQL Server 没有数组
  • 你想用这个查询做什么?寻找城市之间的路径?以 CSV 格式返回路径?这些是不同的问题。 SQL Server 添加了基本的图形支持和 STRING_AGG。在以前的版本中,您必须 a) 找到一种使用 CTE 计算路径的方法,b) 汇总结果以构建 CSV。字符串连接有很多解决方案。将 CTE 用于图形路径更难

标签: sql-server tsql common-table-expression recursive-query


【解决方案1】:

试试下面的

-- Paths from Palermo to Milano...
;WITH both_ways (
    from_city,
    to_city,
    distance
) /* Working Table containing all ways */
AS (
    SELECT
        from_city,
        to_city,
        distance
    FROM pairs
UNION ALL
    SELECT
        to_city AS "from_city",
        from_city AS "to_city",
        distance
    FROM pairs
),
paths (
    from_city,
    to_city,
    distance,
    path,
    Step
)
AS (
    SELECT
        from_city,
        to_city,
        distance,
        CAST(CONCAT('[',from_city,']') AS varchar(MAX)) AS "path",
        1 Step
    FROM both_ways b1
    WHERE b1.from_city = 'Palermo' --<<< Start Node >>>
  UNION ALL
    SELECT
        b2.from_city,
        b2.to_city,
        p.distance + b2.distance,
        p.path + CONCAT('[',b2.from_city,']'),
        p.Step+1
    FROM both_ways b2
    JOIN paths p
         ON (p.to_city = b2.from_city
             AND CHARINDEX(CONCAT('[',b2.from_city,']'),p.path)=0 /* Prevent re-tracing */
             AND p.Step < 6)
)
SELECT TOP 5
    REPLACE(REPLACE(REPLACE(path,'][',','),'[',''),']',',') + to_city AS "path",
    distance
FROM paths
WHERE to_city = 'Milano'  --<<< End node >>>

  AND CHARINDEX('[Napoli]',path)>0
  AND CHARINDEX('[Roma]',path)>0
  AND CHARINDEX('[Bari]',path)>0  -- <<< via... >>> - <@ means 'is contained by' 

ORDER BY distance, path

如果函数 CONCAT 不起作用,那么每个人都使用与 + 的连接

CONCAT('[',from_city,']') => '['+from_city+']'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-08
    • 1970-01-01
    • 2018-08-09
    • 2014-01-04
    • 2017-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多