重用SQL中的子查询列
我有下面的SQL重用SQL中的子查询列,sql,sql-server-2012,Sql,Sql Server 2012,我有下面的SQL SELECT U.ID AS UserID ,U.LoginName AS Name ,PV.Time AS [Time] ,PV.URL AS [Url] ,P.Name AS [Product 1 Name] ,P.SKU AS [Product 1 SKU] ,P.ModelNumber AS [Product 1 Model Number] ,P2.Name AS [Product 2 Name] ,P2
SELECT U.ID AS UserID
,U.LoginName AS Name
,PV.Time AS [Time]
,PV.URL AS [Url]
,P.Name AS [Product 1 Name]
,P.SKU AS [Product 1 SKU]
,P.ModelNumber AS [Product 1 Model Number]
,P2.Name AS [Product 2 Name]
,P2.SKU AS [Product 2 SKU]
,P2.ModelNumber AS [Product 2 Model Number]
,ISNULL((select TOP 1 Value from AttributesValues AV INNER JOIN Attributes A ON AV.AttributeID = A.ID WHERE AV.ProductID = P.ID AND A.RetailerID = 23 AND A.CODE = 'metadata-department'),'') AS Department
,ISNULL((select TOP 1 Value from AttributesValues AV INNER JOIN Attributes A ON AV.AttributeID = A.ID WHERE AV.ProductID = P.ID AND A.RetailerID = 23 AND A.CODE = 'metadata-group'),'') AS Department
,ISNULL((select TOP 1 Value from AttributesValues AV INNER JOIN Attributes A ON AV.AttributeID = A.ID WHERE AV.ProductID = P.ID AND A.RetailerID = 23 AND A.CODE = 'metadata-subgroup'),'') AS SubGroup
,C.Browser AS [Browser]
,C.BrowserVersion AS [Browser Version]
,C.IPAddress AS [IP Address]
,C.UserAgent AS [User Agent]
,C.UserLanguage AS [User Language]
,PV.PageType AS [Page Type]
FROM PageVisits PV
INNER JOIN Users U ON U.ID = PV.UserID
INNER JOIN Clients C ON C.ID = PV.ClientID
INNER JOIN Products P ON P.id = PV.P1ID
LEFT OUTER JOIN Products P2 ON P2.id = PV.P2ID
WHERE P.RetailerID = 23
AND PV.UserID IS NOT NULL
AND PV.PageType IN ('Product','Compare Products')
AND PV.[Time] >= '{0}' AND PV.[Time] < '{1}'
我在这里用了三次。唯一的区别是A.CODE=。如何改进这一点您应该首先尝试为查询建立索引:
create index on Attributes(RetailerId, Code, Id);
create index on AttributeValues(AttributeId, ProductId, Value);
子查询的处理应该只是几个索引查找。您应该首先尝试为查询构建索引:
create index on Attributes(RetailerId, Code, Id);
create index on AttributeValues(AttributeId, ProductId, Value);
子查询的处理应该只是几个索引查找。始终使用ORDER BY with TOP。否则,您将得到不确定的结果,这取决于SQL引擎将如何获取相关行
如果实际上不需要TOP 1,即如果子查询始终返回1或0行,而没有TOP,则可以使用EXTER APPLY with MAX:
始终使用带有顶部的ORDER BY。否则,您将得到不确定的结果,这取决于SQL引擎将如何获取相关行
如果实际上不需要TOP 1,即如果子查询始终返回1或0行,而没有TOP,则可以使用EXTER APPLY with MAX:
您可以定义一个CTE,它基本上是一个内联视图,以避免重新键入查询,但它实际上不会更改正在执行的查询3次,它只会整理代码:
WITH CTE AS
( SELECT AV.ProductID, AV.Value, A.Code
FROM AttributesValues AV
INNER JOIN Attributes A ON AV.AttributeID = A.ID
WHERE A.RetailerID = 23
)
SELECT U.ID AS UserID
,U.LoginName AS Name
,PV.Time AS [Time]
,PV.URL AS [Url]
,P.Name AS [Product 1 Name]
,P.SKU AS [Product 1 SKU]
,P.ModelNumber AS [Product 1 Model Number]
,P2.Name AS [Product 2 Name]
,P2.SKU AS [Product 2 SKU]
,P2.ModelNumber AS [Product 2 Model Number]
,ISNULL((SELECT TOP 1 Value FROM CTE WHERE CTE.ProductID = P.ID AND CTE.CODE = 'metadata-department'),'') AS Department
,ISNULL((SELECT TOP 1 Value FROM CTE WHERE CTE.ProductID = P.ID AND CTE.CODE = 'metadata-group'),'') AS [Group]
,ISNULL((SELECT TOP 1 Value FROM CTE WHERE CTE.ProductID = P.ID AND CTE.CODE = 'metadata-subgroup'),'') AS SubGroup
,C.Browser AS [Browser]
,C.BrowserVersion AS [Browser Version]
,C.IPAddress AS [IP Address]
,C.UserAgent AS [User Agent]
,C.UserLanguage AS [User Language]
,PV.PageType AS [Page Type]
FROM PageVisits PV
INNER JOIN Users U ON U.ID = PV.UserID
INNER JOIN Clients C ON C.ID = PV.ClientID
INNER JOIN Products P ON P.id = PV.P1ID
LEFT OUTER JOIN Products P2 ON P2.id = PV.P2ID
WHERE P.RetailerID = 23
AND PV.UserID IS NOT NULL
AND PV.PageType IN ('Product','Compare Products')
AND PV.[Time] >= '{0}' AND PV.[Time] < '{1}'
N> B您可能希望更改行号中的ORDER BY,以影响productID和代码的每个组合返回的值。如果这是唯一的,ORDER BY是不相关的,尽管*您可以定义一个CTE,它基本上是一个内联视图,以避免重新键入查询,但实际上不会更改正在执行的查询3次,它只会整理代码:
WITH CTE AS
( SELECT AV.ProductID, AV.Value, A.Code
FROM AttributesValues AV
INNER JOIN Attributes A ON AV.AttributeID = A.ID
WHERE A.RetailerID = 23
)
SELECT U.ID AS UserID
,U.LoginName AS Name
,PV.Time AS [Time]
,PV.URL AS [Url]
,P.Name AS [Product 1 Name]
,P.SKU AS [Product 1 SKU]
,P.ModelNumber AS [Product 1 Model Number]
,P2.Name AS [Product 2 Name]
,P2.SKU AS [Product 2 SKU]
,P2.ModelNumber AS [Product 2 Model Number]
,ISNULL((SELECT TOP 1 Value FROM CTE WHERE CTE.ProductID = P.ID AND CTE.CODE = 'metadata-department'),'') AS Department
,ISNULL((SELECT TOP 1 Value FROM CTE WHERE CTE.ProductID = P.ID AND CTE.CODE = 'metadata-group'),'') AS [Group]
,ISNULL((SELECT TOP 1 Value FROM CTE WHERE CTE.ProductID = P.ID AND CTE.CODE = 'metadata-subgroup'),'') AS SubGroup
,C.Browser AS [Browser]
,C.BrowserVersion AS [Browser Version]
,C.IPAddress AS [IP Address]
,C.UserAgent AS [User Agent]
,C.UserLanguage AS [User Language]
,PV.PageType AS [Page Type]
FROM PageVisits PV
INNER JOIN Users U ON U.ID = PV.UserID
INNER JOIN Clients C ON C.ID = PV.ClientID
INNER JOIN Products P ON P.id = PV.P1ID
LEFT OUTER JOIN Products P2 ON P2.id = PV.P2ID
WHERE P.RetailerID = 23
AND PV.UserID IS NOT NULL
AND PV.PageType IN ('Product','Compare Products')
AND PV.[Time] >= '{0}' AND PV.[Time] < '{1}'
N> B您可能希望更改行号中的ORDER BY,以影响productID和代码的每个组合返回的值。如果这是唯一的,则ORDER BY与问题无关*与问题无关:TOP应仅与ORDER BY一起使用。创建视图以缩短子查询中的子查询,你有一个没有订单的TOP BY。准备临时表subquery@ypercube,这有什么区别吗?与问题无关:TOP应仅与ORDER BY一起使用。创建视图以缩短子查询在子查询中,您有TOP而没有ORDER BY。准备临时表subquery@ypercube,这有什么区别吗?好的。但是有人告诉我索引会使INSERT/UPDATE/DELETE变慢?@user960567这取决于对这些语句感兴趣的列以及索引定义中设置的列。@user960567。索引将降低数据插入操作的速度。是否使用它们取决于系统上的相对负载。这个问题没有涉及数据修改负载。+1,索引建议非常有用@在user960567中,索引通常会增强使用它们的SELECT查询和一些INSERT/UPDATE/DELETE查询,并带来巨大的性能优势。插入和某些更新/删除的速度通常很慢。确定。但是有人告诉我索引会使INSERT/UPDATE/DELETE变慢?@user960567这取决于对这些语句感兴趣的列以及索引定义中设置的列。@user960567。索引将降低数据插入操作的速度。是否使用它们取决于系统上的相对负载。这个问题没有涉及数据修改负载。+1,索引建议非常有用@在user960567中,索引通常会增强使用它们的SELECT查询和一些INSERT/UPDATE/DELETE查询,并带来巨大的性能优势。插入和某些更新/删除的速度通常很慢。
WITH CTE AS
( SELECT AV.ProductID,
AV.Value,
A.Code ,
RowNumber = ROW_NUMBER() OVER(PARTITION BY AV.ProductID, A.Code ORDER BY AV.Value)
FROM AttributesValues AV
INNER JOIN Attributes A ON AV.AttributeID = A.ID
WHERE A.RetailerID = 23
AND AV.Code IN ('metadata-department', 'metadata-group', 'metadata-subgroup')
), AV AS
( SELECT pvt.ProductID,
pvt.[metadata-department],
pvt.[metadata-group],
pvt.[metadata-subgroup]
FROM CTE
PIVOT
( MAX(Value)
FOR Code IN ([metadata-department], [metadata-group], [metadata-subgroup])
) pvt
WHERE pvt.RowNumber = 1
)
SELECT U.ID AS UserID
,U.LoginName AS Name
,PV.Time AS [Time]
,PV.URL AS [Url]
,P.Name AS [Product 1 Name]
,P.SKU AS [Product 1 SKU]
,P.ModelNumber AS [Product 1 Model Number]
,P2.Name AS [Product 2 Name]
,P2.SKU AS [Product 2 SKU]
,P2.ModelNumber AS [Product 2 Model Number]
,ISNULL(AV.[metadata-department],'') AS Department
,ISNULL(AV.[metadata-group],'') AS [Group]
,ISNULL(AV.[metadata-subgroup],'') AS SubGroup
,C.Browser AS [Browser]
,C.BrowserVersion AS [Browser Version]
,C.IPAddress AS [IP Address]
,C.UserAgent AS [User Agent]
,C.UserLanguage AS [User Language]
,PV.PageType AS [Page Type]
FROM PageVisits PV
INNER JOIN Users U ON U.ID = PV.UserID
INNER JOIN Clients C ON C.ID = PV.ClientID
INNER JOIN Products P ON P.id = PV.P1ID
LEFT OUTER JOIN Products P2 ON P2.id = PV.P2ID
LEFT OUTER JOIN AV ON AV.ProductID = p.ID
WHERE P.RetailerID = 23
AND PV.UserID IS NOT NULL
AND PV.PageType IN ('Product','Compare Products')
AND PV.[Time] >= '{0}' AND PV.[Time] < '{1}'