没有临时表的SQL查询

时间:2011-09-26 04:02:58

标签: sql sql-server-2005

我编写了一个在我的本地SQL Server 2005上运行良好的查询。我将查询上传到我的托管服务器,不知怎的,他们说在他们的服务器上禁用了临时表创建。

我的查询看起来像这样

create table #tmp
(
    srno int identity (1,1) ,
    orderid int,
    orderdate datetime,
    product_code varchar(255),
    product_name varchar(255),
    shipping_cost decimal(18,2)
)

insert into #tmp (orderid, orderdate, product_code, product_name, shipping_cost)
   (select distinct 
      ord.orderid, ord.orderdate, odn.productcode,
      odn.productname, ord.totalshippingcost  
    from OrderNew ord
    inner join order_detailsnew odn on ord.orderid = odn.orderid)

declare @rowcount int, @flag int, @orderid int

set @rowcount = (select @@ROWCOUNT)

set @flag = 0

while (@flag <@rowcount)
begin
   set @orderid = (select orderid from #tmp where srno = @flag + 1)

   if exists (select 1 from #tmp where orderid = @orderid )
   begin
      update #tmp 
      set shipping_cost = 0.0 
      where srno IN (select srno from #tmp 
                     where orderid = @orderid 
                     AND srno NOT IN (SELECT TOP 1 srno FROM #tmp where orderid = @orderid))

   end
   set @flag = @flag+1
end

select * from #tmp
drop table #tmp

所以不确定这个查询是否可以在没有临时表的情况下编写,加入等不确定它是否可行?有什么建议吗?

1 个答案:

答案 0 :(得分:1)

我认为这个查询是为了输入一个报告,这就是为什么你只需要一次总运费,而你不需要一个临时表供参考,如果你需要,你总是可以这样做: / p>

DECLARE @tmp TABLE 
(
    srno int identity (1,1) ,
    orderid int,
    orderdate datetime,
    product_code varchar(255),
    product_name varchar(255),
    shipping_cost decimal(18,2)
)

并使用@tmp而不是#tmp

但你不需要临时表,见下文:

SELECT ord.orderid, ord.orderdate, odn.productcode, odn.productname, ord.totalshippingcost
FROM OrderNew AS ord
    INNER JOIN order_detailsnew AS odn ON odn.orderid = ord.orderid
WHERE odn.productcode = (SELECT MIN(productcode) FROM OrderNew AS odn2 WHERE odn2.orderid = ord.orderid)
UNION ALL
SELECT ord.orderid, ord.orderdate, odn.productcode, odn.productname, 0.0 AS totalshippingcost
FROM OrderNew AS ord
    INNER JOIN order_detailsnew AS odn ON odn.orderid = ord.orderid
WHERE odn.productcode > (SELECT MIN(productcode) FROM OrderNew AS odn2 WHERE odn2.orderid = ord.orderid)
ORDER BY ord.orderid, ord.orderdate, odn.productcode

使用以下测试脚本为我工作正常:

DECLARE @ord TABLE
(
    orderid int,
    orderdate datetime,
    totalshippingcost decimal(18,2)
)
DECLARE @odn TABLE
(
    orderid int,
    productcode varchar(255),
    productname varchar(255)
)

INSERT INTO @ord VALUES(1, CAST('20110101' AS DATETIME), 50.25)
INSERT INTO @ord VALUES(2, CAST('20110105' AS DATETIME), 78.15)
INSERT INTO @ord VALUES(3, CAST('20110112' AS DATETIME), 65.50)
INSERT INTO @ord VALUES(4, CAST('20110112' AS DATETIME), 128.00)

INSERT INTO @odn VALUES(1, 'aa', 'AAA')
INSERT INTO @odn VALUES(1, 'bb', 'BBB')
INSERT INTO @odn VALUES(1, 'cc', 'CCC')
INSERT INTO @odn VALUES(2, 'aa', 'AAA')
INSERT INTO @odn VALUES(2, 'bb', 'BBB')
INSERT INTO @odn VALUES(3, 'bb', 'BBB')
INSERT INTO @odn VALUES(3, 'cc', 'CCC')
INSERT INTO @odn VALUES(4, 'cc', 'CCC')

我的结果:

Result Set (8 items)  
orderid | orderdate           | productcode | productname | totalshippingcost
1       | 01/01/2011 00:00:00 | aa          | AAA         | 50.25
1       | 01/01/2011 00:00:00 | bb          | BBB         | 0.00
1       | 01/01/2011 00:00:00 | cc          | CCC         | 0.00
2       | 05/01/2011 00:00:00 | aa          | AAA         | 78.15
2       | 05/01/2011 00:00:00 | bb          | BBB         | 0.00
3       | 12/01/2011 00:00:00 | bb          | BBB         | 65.50
3       | 12/01/2011 00:00:00 | cc          | CCC         | 0.00
4       | 12/01/2011 00:00:00 | cc          | CCC         | 128.00

编辑:我对上述解决方案不满意,这是一种更快,更优雅的方式:

SELECT ord.orderid, ord.orderdate, ord.productcode, ord.productname, CASE WHEN row_no = 1 THEN ord.totalshippingcost ELSE 0.0 END AS totalshippingcost
FROM
(
SELECT ROW_NUMBER() OVER(PARTITION BY ord.orderid ORDER BY ord.orderid, ord.orderdate, odn.productcode) AS row_no, ord.orderid, ord.orderdate, odn.productcode, odn.productname, ord.totalshippingcost
FROM OrderNew AS ord
    INNER JOIN order_detailsnew AS odn ON odn.orderid = ord.orderid
) ord
ORDER BY ord.orderid, ord.orderdate, ord.productcode

结果完美匹配。

编辑user580950,将空值插入每隔一行:

您将第一个SELECT行更改为:

SELECT CASE D.N WHEN 1 THEN ord.orderid END AS orderid, ...

你有机会订购ORDER BY:

CROSS JOIN (SELECT 1 UNION ALL SELECT 2) AS D(N)
ORDER BY ord.orderid, ord.orderdate, ord.productcode, D.N

但正如评论中所述,在你的另一个问题SQL Query Add an Alternate Blank Records中说,这是你应该在你的表示层而不是在数据库中做的事情。