2015-04-15 4 views
0

Этот запрос дает мне желаемый результат, но я не могу запускать этот запрос каждый раз. Две петли стоят меня. Поэтому мне нужно реализовать что-то вроде view.But логика имеет временные таблицы, которые не допускаются в представлениях Также, есть ли другой способ сохранить этот результат или изменить запрос так, чтобы он обойдется мне меньше.Как настроить следующий запрос?

DECLARE @Temp TABLE (
    [SiteID] VARCHAR(100) 
    ,[StructureID] INT 
    ,[row] DECIMAL(4, 2) 
    ,[col] DECIMAL(4, 2) 
    ) 
DECLARE @siteID VARCHAR(100) 
    ,@structureID INT 
    ,@struct_row INT 
    ,@struct_col INT 
    ,@rows_count INT 
    ,@cols_count INT 
    ,@row INT 
    ,@col INT 

DECLARE structure_cursor CURSOR 
FOR 
SELECT StructureID 
    ,SiteID 
    ,Cols/8.5 AS Cols 
    ,Rows/11 AS Rows 
FROM Structure 
WHERE SellerID = 658 --AND StructureID = 55 

OPEN structure_cursor 

FETCH NEXT 
FROM structure_cursor 
INTO @structureID 
    ,@siteID 
    ,@struct_col 
    ,@struct_row 

SELECT @rows_count = 1 
    ,@cols_count = 1 
    ,@row = 1 
    ,@col = 1 

WHILE @@FETCH_STATUS = 0 
BEGIN 
    WHILE @row <= @struct_row 
    BEGIN 
     WHILE @col <= @struct_col 
     BEGIN 
      --PRINT 'MEssage'; 
      INSERT INTO @Temp (
       SiteID 
       ,StructureID 
       ,row 
       ,col 
       ) 
      VALUES (
       @siteID 
       ,@structureID 
       ,@rows_count 
       ,@cols_count 
       ) 

      SET @cols_count = @cols_count + 1; 
      SET @col = @col + 1; 
     END 

     SET @cols_count = 1; 
     SET @col = 1; 
     SET @rows_count = @rows_count + 1; 
     SET @row = @row + 1; 
    END 

    SET @row = 1; 
    SET @col = 1; 
    SET @rows_count = 1; 

    FETCH NEXT 
    FROM structure_cursor 
    INTO @structureID 
     ,@siteID 
     ,@struct_col 
     ,@struct_row 
END 

CLOSE structure_cursor; 

DEALLOCATE structure_cursor; 

SELECT * FROM @Temp 

Image 1 Image 2

+0

Пожалуйста, пост выборочные данные и ожидаемые результаты. –

+0

Я фактически конвертирую таблицу 1, как показано на рисунке выше, в таблицу 2. Так что я могу использовать вторую таблицу далее в своем запросе, чтобы присоединиться и получить результат –

ответ

1

Вы можете сгенерировать количество строк и столбцов, а затем CROSS APPLY с такими, как показано ниже. Я не учитывал состояние вашего продавца.

;WITH Cols 
AS 
(
    SELECT StructureID, SiteID, CAST(Cols/8.5 AS INT) AS Col 
    FROM Structure 
    UNION ALL 
    SELECT s.StructureID, s.SiteID, Col - 1 
    FROM Structure s 
     INNER JOIN Cols c ON s.StructureID = c.StructureID AND s.SiteID = c.SiteID 
    WHERE Col > 1 
) 
, Rows 
AS 
(
    SELECT StructureID, SiteID, CAST(Rows/11 AS INT) AS Row 
    FROM Structure 
    UNION ALL 
    SELECT s.StructureID, s.SiteID, Row - 1 
    FROM Structure s 
     INNER JOIN Rows r ON s.StructureID = r.StructureID AND s.SiteID = r.SiteID 
    WHERE Row > 1 
) 
--INSERT INTO @Temp (SiteID, StructureID, row, col) 
SELECT s.SiteID, s.StructureID, r.Row, c.Col 
FROM Structure s 
    CROSS APPLY Cols c 
    CROSS APPLY Rows r 
WHERE s.StructureID = c.StructureID AND s.SiteID = c.SiteID 
    AND s.StructureID = r.StructureID AND s.SiteID = r.SiteID 
+0

Спасибо! это помогло мне также создать представление. Не могли бы вы подробнее рассказать о том, как вы можете сделать этот Col-1 в CTE выше. –

+1

Это рекурсивный CTE. Вы устанавливаете в якоре наибольшее число для col/row (Rows/11 и Cols/8.5), затем в рекурсивном члене вы продолжаете вычитать до тех пор, пока не получите 1. –

+0

Отлично! Большое спасибо. –

2

ли это с операцией на основе набора. Я думаю, что вы просто хотите insert . . . select:

INSERT INTO @Temp (SiteID, StructureID, row, col) 
    SELECT StructureID, SiteID, Cols/8.5 AS Cols, Rows/11 AS Rows 
    FROM Structure 
    WHERE SellerID = 658; 

Вы должны избегать курсоров, если вы действительно не нуждаетесь в них по какой-то причине (например, вызов хранимой процедуры или с использованием динамического SQL в каждой строке).

EDIT:

Чтение логики, это выглядит, как вы хотите, чтобы вставить строки в соответствии с лимитами в каждой строке. Вы все еще не хотите использовать курсор. Для этого вам нужен генератор чисел, а master..spt_values - удобный, если он имеет достаточно строк. Итак:

with n as (
     select row_number() over (order by (select null)) as n 
     from master..spt_values 
    ) 
INSERT INTO @Temp (SiteID, StructureID, row, col) 
    SELECT StructureID, SiteID, ncol.n/8.5 AS Cols, nrow.n/11 AS Rows 
    FROM Structure s JOIN 
     n ncol 
     ON ncol.n <= s.struct_col CROSS JOIN 
     n nrow 
     ON nrow <= s.struct_row 
    WHERE SellerID = 658; 
+0

Хорошо, я попробую и скоро вернусь. Спасибо! ! –

0

Мы можем сделать это с помощью CROSS APPLY и CTE.

CREATE TABLE Structure(SiteID varchar(20), StructureID int, 
Cols decimal(18,2), [Rows] decimal(18,2)) 

INSERT INTO Structure (SiteID, StructureID, Cols, [Rows]) 

VALUES 

('MN353970', 51,17,22), 
('MN272252', 52,17,11) 


;WITH RowCTE([Rows]) AS 
(
    SELECT 1 
    UNION ALL 
    SELECT 2 
), 
ColCTE(Cols) AS 
(
    SELECT 1 
    UNION ALL 
    SELECT 2 
) 

SELECT SiteID, StructureID, R.Rows, C.Cols 
FROM Structure s 
CROSS APPLY 
    (
     SELECT Cols FROM ColCTE 
    ) C 
CROSS APPLY 
    (
     SELECT [Rows] FROM RowCTE 
    ) R 

Sql Fiddle Demo

+0

Привет, selva..и посмотрел на ваш код..Логика выглядит нормально, но смотря на siteID MN272252..это должно просто создать 2 строки не 4 строки, потому что их, Cols/8.5 AS Cols и Rows/11 AS Rows.Which означает, что 2x1 должен выход. Выход должен быть динамическим. –

Смежные вопросы