2015-04-15 27 views
0

这个查询给了我想要的结果,但我无法每次都运行这个查询。这2个循环耗费了我所有的费用。所以我需要实现类似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,如下所示。我遗漏了您的SellerID条件。

;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

谢谢!这也帮助我创建了视图。可以详细说明如何在CTE上面执行Col-1 .. –

+1

这是一个递归CTE。你在锚点设置了最高数字(col/row)(行/ 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)。

编辑:

读逻辑,它看起来像你想基于每行的限制插入行。你仍然不想使用游标。为此,您需要一个数字生成器,并且如果它有足够的行,则是一个方便的数字生成器。因此:

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 APPLYCTE做到这一点。

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和行/ 11 AS行。这意味着2x1应该作为输出。输出应该是动态的。 –