如何调整以下查询?
How to tune the following query?
这个查询给了我想要的结果,但我不能 运行 这个查询每 time.The 2 个循环花费 me.So 我需要实现类似 view.But 的东西逻辑涉及临时表,在 well.so 的视图中不允许使用临时表,是否有任何其他方法来存储此结果或更改查询以降低成本。
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
使用基于集合的操作执行此操作。我想你只是想要 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)。
编辑:
阅读逻辑,您似乎想要根据每行中的限制插入行。您仍然不想使用游标。为此,您需要一个数字生成器,而 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;
您可以生成行数和列数,然后与它们交叉应用,如下所示。我遗漏了您的 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
我们可以使用 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
这个查询给了我想要的结果,但我不能 运行 这个查询每 time.The 2 个循环花费 me.So 我需要实现类似 view.But 的东西逻辑涉及临时表,在 well.so 的视图中不允许使用临时表,是否有任何其他方法来存储此结果或更改查询以降低成本。
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
使用基于集合的操作执行此操作。我想你只是想要 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)。
编辑:
阅读逻辑,您似乎想要根据每行中的限制插入行。您仍然不想使用游标。为此,您需要一个数字生成器,而 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;
您可以生成行数和列数,然后与它们交叉应用,如下所示。我遗漏了您的 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
我们可以使用 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