【解决马上结贴】SQL中With as 为什么不可以这样用啊..

sunlovesea 2009-03-17 11:32:56
如果这样就可以
WITH tb as
(
SELECT * FROM SCE.Booth
)
SELECT * FROM tb
但我改成下面的方法就不行..
DECLARE @sql varchar(4000)
SET @sql= 'SELECT * FROM SCE.Booth'
WITH tb as
(
EXEC(@sql)
)
SELECT * FROM tb


如何改可以是上面的运行呢?
...全文
269 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
zzxap 2009-03-17
  • 打赏
  • 举报
回复
[CODE=SQL]
SELECT
sku,
sum(initqty) as initqty,
sum(inqty) as inqty,sum(outqty) as outqty,
sum(lastqty) as lastqty
FROM (
SELECT sku,lastqty as initqty,0 as inqty,0 as outqty,0 as lastqty
FROM fin
WHERE day=to_date('20030713','yyyymmdd')
UNION ALL
SELECT sku,0 as initqty,inqty,outqty,0 as lastqty
FROM fin
WHERE day>=to_date('20030714','yyyymmdd') and day<=to_date('20030714','yyyymmdd')
UNION ALL
SELECT sku,0 as initqty,0 as inqty,0 as outqty,lastqty
FROM fin
WHERE day=to_date('20030714','yyyymmdd')
)
GROUP BY sku;
我们来看该SQL所花费的时间为:
SQL> set timing on
SQL> /
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
SKU INITQTY INQTY OUTQTY LASTQTY
-------- ---------- ---------- ---------- ----------
00106162 0 0 12 60
00106467 0 20 10 60
已选择956行。

已用时间: 00: 00: 19.08

然后,我们来对该SQL进行改写一番,如下所示:
WITH result AS (
SELECT /*+ materialize */ day,sku,inqty,outqty,lastqty
FROM fin
WHERE day>=to_date('20030713','yyyymmdd') AND day<=to_date('20030714','yyyymmdd'))
SELECT
sku,
sum(initqty) as initqty,
sum(inqty) as inqty,
sum(outqty) as outqty,
sum(lastqty) as lastqty
FROM (
SELECT sku,lastqty as initqty,0 as inqty,0 as outqty,0 as lastqty
FROM result
WHERE day=to_date('20030713','yyyymmdd')
UNION ALL
SELECT sku,0 as initqty,inqty,outqty,0 as lastqty
FROM result
WHERE day=to_date('20030714','yyyymmdd')
UNION ALL
SELECT sku,0 as initqty,0 as inqty,0 as outqty,lastqty
FROM result
WHERE day=to_date('20030714','yyyymmdd')
)
GROUP BY sku;

我们来看修改后的SQL所花费的时间为:
SQL> set timing on
SQL> /
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
SKU INITQTY INQTY OUTQTY LASTQTY
-------- ---------- ---------- ---------- ----------
00106162 0 0 12 60
00106467 0 20 10 60
已选择956行。

已用时间: 00: 00: 06.06

从这里可以看到,通过WITH AS可以从20秒降低到6秒,几乎提高了65%的性能。

[/CODE]
zzxap 2009-03-17
  • 打赏
  • 举报
回复
公用表表达式(CTE)
CTE的语法:
[ WITH <common_table_expression> [ , n ] ]
<common_table_expression>::=
expression_name [ ( column_name [ , n ] ) ]
AS
( CTE_query_definition )
在使用CTE时应注意如下几点:
1. CTE后面必须直接跟使用CTE的SQL语句(如select、insert、update等),否则,CTE将失效。如下面的SQL语句将无法正常使用CTE:
2. CTE后面也可以跟其他的CTE,但只能使用一个with,多个CTE中间用逗号(,)分隔
3. 如果CTE的表达式名称与某个数据表或视图重名,则紧跟在该CTE后面的SQL语句使用的仍然是CTE
4. CTE 可以引用自身,也可以引用在同一 WITH 子句中预先定义的 CTE。不允许前向引用。
5. 不能在 CTE_query_definition 中使用以下子句:
(1)COMPUTE 或 COMPUTE BY
(2)ORDER BY(除非指定了 TOP 子句)
(3)INTO
(4)带有查询提示的 OPTION 子句
(5)FOR XML
(6)FOR BROWSE
6. 如果将 CTE 用在属于批处理的一部分的语句中,那么在它之前的语句必须以分号结尾
zzxap 2009-03-17
  • 打赏
  • 举报
回复
[code=SQL]

1 :普通SQL语句可以用Exec执行

eg: Select * from tableName
Exec('select * from tableName')
Exec sp_executesql N'select * from tableName' -- 请注意字符串前一定要加N

2:字段名,表名,数据库名之类作为变量时,必须用动态SQL

eg:
declare @fname varchar(20)
set @fname = 'FiledName'
Select @fname from tableName -- 错误,不会提示错误,但结果为固定值FiledName,并非所要。
Exec('select ' + @fname + ' from tableName') -- 请注意 加号前后的 单引号的边上加空格

当然将字符串改成变量的形式也可
declare @fname varchar(20)
set @fname = 'FiledName' --设置字段名

declare @s varchar(1000)
set @s = 'select ' + @fname + ' from tableName'
Exec(@s) -- 成功
exec sp_executesql @s -- 此句会报错

declare @s Nvarchar(1000) -- 注意此处改为nvarchar(1000)
set @s = 'select ' + @fname + ' from tableName'
Exec(@s) -- 成功
exec sp_executesql @s -- 此句正确

3. 输出参数
declare @num int,
@sqls nvarchar(4000)
set @sqls='select count(*) from tableName'
exec(@sqls)
--如何将exec执行结果放入变量中?

declare @num int,
@sqls nvarchar(4000)
set @sqls='select @a=count(*) from tableName '
exec sp_executesql @sqls,N'@a int output',@num output
select @num

[/CODE]
sunlovesea 2009-03-17
  • 打赏
  • 举报
回复
谢谢:codehenry.com
time_is_life 2009-03-17
  • 打赏
  • 举报
回复

[ WITH <common_table_expression> [ ,...n ] ]

<common_table_expression>::=
expression_name [ ( column_name [ ,...n ] ) ]
AS
( CTE_query_definition )



CTE_query_definition
Specifies a SELECT statement whose result set populates the common table expression. The SELECT statement for CTE_query_definition must meet the same requirements as for creating a view, except a CTE cannot define another


从以上描述可以看出,as 后面必须是一个SELECT 语句

62,268

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧