7

我有这个 Oracle 代码结构,我正在尝试转换为 SQL Server 2008 注意:我在方括号“[]”中使用了通用名称、封闭的列名和表名,并进行了一些格式化以使代码更多可读)

SELECT [col#1], [col#2], [col#3], ..., [col#n], [LEVEL] 
FROM (SELECT [col#1], [col#2], [col#3], ..., [col#n] 
      FROM [TABLE_1] 
      WHERE ... ) 
CONNECT BY PRIOR [col#1] = [col#2] 
START WITH [col#2] IS NULL 
ORDER SIBLINGS BY [col#3]

上述代码的 SQL Server 等效模板是什么?

具体来说,我正在努力使用LEVEL和 'ORDER SIBLINGS BY' Oracle 构造。

注意: 上面的“代码”是一组 Oracle 程序的最终输出。基本上,“WHERE”子句是动态构建的,并根据传递的各种参数而变化。以“CONNECT BY PRIOR”开头的代码块是硬编码的。


以供参考:

SQL SERVER 文章中 ORACLE 的 CONNECT BY PRIOR 模拟接近了,但它没有解释如何处理 'LEVEL' 和 'ORDER SIBLINGS' 构造。......我的心变得扭曲了!

SELECT name 
  FROM emp
  START WITH name = 'Joan'
  CONNECT BY PRIOR empid = mgrid

相当于:

WITH n(empid, name) AS 
   (SELECT empid, name 
    FROM emp
    WHERE name = 'Joan'
        UNION ALL
    SELECT nplus1.empid, nplus1.name 
    FROM emp as nplus1, n
    WHERE n.empid = nplus1.mgrid)
SELECT name FROM n

如果我有一个初始模板可供使用,它将大大有助于我构建 SQL Server 存储过程以构建正确的 T-SQL 语句。

援助将不胜感激。

4

3 回答 3

14

模拟 LEVEL 列

通过在递归部分增加一个计数器可以很容易地模拟级别列:

WITH tree (empid, name, level) AS  (
  SELECT empid, name, 1 as level
  FROM emp
  WHERE name = 'Joan'

  UNION ALL

  SELECT child.empid, child.name, parent.level + 1
  FROM emp as child
    JOIN tree parent on parent.empid = child.mgrid
)
SELECT name 
FROM tree;

模拟order siblings by

模拟的order siblings by有点复杂。假设我们有一列sort_order定义了每个父元素的顺序(不是整体排序顺序 - 因为那样order siblings就没有必要了),那么我们可以创建一个列来为我们提供整体排序顺序:

WITH tree (empid, name, level, sort_path) AS  (
  SELECT empid, name, 1 as level, 
         cast('/' + right('000000' + CONVERT(varchar, sort_order), 6) as varchar(max))
  FROM emp
  WHERE name = 'Joan'

  UNION ALL

  SELECT child.empid, child.name, parent.level + 1, 
         parent.sort_path + '/' + right('000000' + CONVERT(varchar, child.sort_order), 6) 
  FROM emp as child
    JOIN tree parent on parent.empid = child.mgrid
)
SELECT * 
FROM tree
order by sort_path;

表达式sort_path看起来很复杂,因为 SQL Server(至少是您正在使用的版本)没有简单的函数来格式化带有前导零的数字。在 Postgres 中,我将使用整数数组,这样就varchar不需要转换为 - 但这在 SQL Server 中也不起作用。

于 2015-08-05T14:25:12.133 回答
0

用户“a_horse_with_no_name”给出的选项对我有用。我更改了代码并将其应用于菜单生成器查询,它第一次工作。这是代码:

WITH tree(option_id,
       option_description,
      option_url,
      option_icon,
      option_level,
      sort_path)
     AS (
     SELECT ppo.option_id,
            ppo.option_description,
          ppo.option_url,
          ppo.option_icon,
          1 AS option_level,
          CAST('/' + RIGHT('00' + CONVERT(VARCHAR, ppo.option_index), 6) AS VARCHAR(MAX))
     FROM security.options_table_name ppo
     WHERE ppo.option_parent_id IS NULL
     UNION ALL
     SELECT co.option_id,
            co.option_description,
          co.option_url,
          co.option_icon,
          po.option_level + 1,
          po.sort_path + '/' + RIGHT('00' + CONVERT(VARCHAR, co.option_index), 6)
     FROM security.options_table_name co,
          tree AS po
     WHERE po.option_id = co.option_parent_id)
     SELECT *
     FROM tree
    ORDER BY sort_path;
于 2017-10-30T15:46:39.873 回答
0

获取最近 10 天的日期:

SELECT DISTINCT RecordDate = DATEADD(DAY,-number,CAST(GETDATE() AS DATE)) 
FROM master..[spt_values] 
WHERE number BETWEEN 1 AND 10
于 2020-06-10T06:54:54.780 回答