SQL Query without Temporary Table
I have written a query which works great on my local SQL Server 2005. I uploaded the query to my hosting server and somehow they say that temporary table creation is disabled on their server.
My query looks like this
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
So not sure if this query can be written without a temporary table, joins etc not sure if it will work ? Any advise ?
I presume this query is to feed into a report which is why you only want the total shipping cost once, while you don't need a temp table for this for reference you can always do this instead if you need to:
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)
)
and use @tmp rather than #tmp
But you shouldn't need a temp table for this, see below:
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
Works fine for me with the following test script:
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')
And my results:
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
edit: I wasn't happy with the above solution, here's a uch faster and more elegant way of doing it:
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
Results match perfectly.
Edit for user580950, to insert nulls into every second row:
You change the first SELECT line to be:
SELECT CASE D.N WHEN 1 THEN ord.orderid END AS orderid, ...
And you chance the ORDER BY line to be:
CROSS JOIN (SELECT 1 UNION ALL SELECT 2) AS D(N)
ORDER BY ord.orderid, ord.orderdate, ord.productcode, D.N
But as the comments say said in your other question SQL Query Add an Alternate Blank Records, this is something that you should be doing at your presentation layer and not in the database.
精彩评论