SQL Oracle 'CONNECT BY PRIOR' 和 'ORDER SIBLINGS BY' 的服务器等效项
SQL Server Equivalent of Oracle 'CONNECT BY PRIOR', and 'ORDER SIBLINGS BY'
我有这个 Oracle 代码 结构 我正在尝试转换为 SQL Server 2008 (注意: 我在方括号 '[]' 中使用了通用名称、封闭的列名称和 table 名称,并进行了一些格式化以使代码更具可读性):
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 服务器等效 模板 是什么?
具体来说,我正在为 LEVEL 和 'ORDER SIBLINGS BY' Oracle 构造而苦苦挣扎。
注:
上面的 "code" 是一组 Oracle 过程的最终输出。基本上,'WHERE' 子句是动态构建的 并根据传递的各种参数而变化。以'CONNECT BY PRIOR'开头的代码块是硬编码的。
供参考:
Simulation of CONNECT BY PRIOR of ORACLE in SQL SERVER 文章很接近,但它没有解释如何处理 '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 服务器存储过程以构建正确的 T-SQL 语句。
我们将不胜感激。
正在模拟 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 服务器(至少您使用的版本)没有简单的函数来格式化带有前导零的数字。在 Postgres 中,我会使用一个整数数组,这样就不需要转换为 varchar
- 但这在 SQL 服务器中也不起作用。
用户"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;
获取最近 10 天的日期:
SELECT DISTINCT RecordDate = DATEADD(DAY,-number,CAST(GETDATE() AS DATE))
FROM master..[spt_values]
WHERE number BETWEEN 1 AND 10
我有这个 Oracle 代码 结构 我正在尝试转换为 SQL Server 2008 (注意: 我在方括号 '[]' 中使用了通用名称、封闭的列名称和 table 名称,并进行了一些格式化以使代码更具可读性):
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 服务器等效 模板 是什么?
具体来说,我正在为 LEVEL 和 'ORDER SIBLINGS BY' Oracle 构造而苦苦挣扎。
注: 上面的 "code" 是一组 Oracle 过程的最终输出。基本上,'WHERE' 子句是动态构建的 并根据传递的各种参数而变化。以'CONNECT BY PRIOR'开头的代码块是硬编码的。
供参考:
Simulation of CONNECT BY PRIOR of ORACLE in SQL SERVER 文章很接近,但它没有解释如何处理 '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 服务器存储过程以构建正确的 T-SQL 语句。
我们将不胜感激。
正在模拟 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 服务器(至少您使用的版本)没有简单的函数来格式化带有前导零的数字。在 Postgres 中,我会使用一个整数数组,这样就不需要转换为 varchar
- 但这在 SQL 服务器中也不起作用。
用户"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;
获取最近 10 天的日期:
SELECT DISTINCT RecordDate = DATEADD(DAY,-number,CAST(GETDATE() AS DATE))
FROM master..[spt_values]
WHERE number BETWEEN 1 AND 10