SQL-запрос без временной таблицы - PullRequest
0 голосов
/ 26 сентября 2011

Я написал запрос, который прекрасно работает на моем локальном SQL Server 2005. Я загрузил запрос на свой хост-сервер, и почему-то они говорят, что создание временных таблиц на их сервере отключено.

Мой запрос выглядит так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

Поэтому не уверены, что этот запрос можно написать без временной таблицы, объединений и т. д., не уверены, что он будет работать?Любой совет?

1 Ответ

1 голос
/ 26 сентября 2011

Я предполагаю, что этот запрос должен быть введен в отчет, поэтому вам нужна только общая стоимость доставки, в то время как вам не нужна временная таблица для этого, для справки вы всегда можете сделать это вместо этого, если вам необходимо:

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

edit: мне не понравилось вышеуказанное решение, вот гораздо более быстрый и элегантный способ сделать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

Результаты полностью совпадают.

Отредактируйте для 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-запрос Добавить альтернативные пустые записи ,это то, что вы должны делать на уровне представления, а не в базе данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...