更好的sql使用where子句计算项目数
我有这个问题,我知道有更好的方法来写它。下面是一个查询,它对订单进行计数,以找出库存中还剩下什么更好的sql使用where子句计算项目数,sql,sql-server,tsql,sql-server-2008,Sql,Sql Server,Tsql,Sql Server 2008,我有这个问题,我知道有更好的方法来写它。下面是一个查询,它对订单进行计数,以找出库存中还剩下什么 DECLARE @reserveDate as Datetime = '10/5/2011 10:20' SELECT p.Name , p.Quantity , (SELECT COUNT(*) FROM [Order] o WHERE o.ProductId = p.Id AND o.Completed =
DECLARE @reserveDate as Datetime = '10/5/2011 10:20'
SELECT p.Name
, p.Quantity
, (SELECT COUNT(*)
FROM [Order] o
WHERE o.ProductId = p.Id
AND o.Completed = 1) as Completed
, (SELECT COUNT(*)
FROM [Order] o
WHERE o.ProductId = p.Id
AND o.Completed <> 1
AND o.ModifiedDate >= @reserveDate) as Reserved
, (SELECT COUNT(*)
FROM [Order] o
WHERE o.ProductId = p.Id
AND o.Completed <> 1
AND o.ModifiedDate < @reserveDate) as ReserveExpired
--, (Quantity - Completed - Reserved) as Available
FROM Product p
您可以在T-SQL本身中减去项,例如: 从ID=1的表中选择A-B作为C
虽然我不确定用子查询实现这一点的最佳方法。我也不知道您是否需要在编程中保留实际数量、已完成、保留和重新服务的Expired值,或者您是否只需要这些值来计算可用数量。如果您需要SQL外部的查询,那么内部的减法将毫无帮助。您可以使用以下方法替换子查询:
SELECT p.Name
, p.Quantity
, SUM(CASE WHEN o.completed = 1 THEN 1 ELSE 0 END) AS Completed
, SUM(CASE WHEN o.completed <> 1 AND o.ModifiedDate >= @reserveDate THEN 1 ELSE 0 END) AS Reserved
, SUM(CASE WHEN o.completed <> 1 AND o.ModifiedDate < @reserveDate THEN 1 ELSE 0 END) AS ReserveExpired
, p.Quantity -
SUM(CASE WHEN o.completed = 1 THEN 1 ELSE 0 END) -
SUM(CASE WHEN o.completed <> 1 AND o.ModifiedDate >= @reserveDate THEN 1 ELSE 0 END) AS available
FROM Product p
LEFT JOIN ORDER o ON o.productid = p.id
GROUP BY p.Name, p.Quantity
或者,以下内容等效且易于阅读:
SELECT x.name,
x.quantity,
x.completed,
x.reserved,
x.reserveexpired,
x.quantity - x.completed - x.reserved AS available
FROM (SELECT p.Name
, p.Quantity
, SUM(CASE WHEN o.completed = 1 THEN 1 ELSE 0 END) AS Completed
, SUM(CASE WHEN o.completed <> 1 AND o.ModifiedDate >= @reserveDate THEN 1 ELSE 0 END) AS Reserved
, SUM(CASE WHEN o.completed <> 1 AND o.ModifiedDate < @reserveDate THEN 1 ELSE 0 END) AS ReserveExpired
FROM Product p
LEFT JOIN ORDER o ON o.productid = p.id
GROUP BY p.Name, p.Quantity) x
可以使用交叉应用/外部应用运算符:
CREATE INDEX aaa
ON [Order](ProductId)
INCLUDE (Completed,ModifiedDate);
PRINT '***** Sol1 *****'
SELECT
p.Name
,p.Quantity
,ISNULL(ca.Completed,0) Completed
,ISNULL(ca.Reserved,0) Reserved
,ISNULL(ca.ReserveExpired,0) ReserveExpired
,p.Quantity - ISNULL(ca.Completed,0) - ISNULL(ca.Reserved,0) Available
FROM Product p
OUTER APPLY
(
SELECT
SUM(CASE WHEN o.Completed = 1 THEN 1 ELSE 0 END) Completed
,SUM(CASE WHEN o.Completed <> 1 AND o.ModifiedDate >= @reserveDate THEN 1 ELSE 0 END) Reserved
,SUM(CASE WHEN o.Completed <> 1 AND o.ModifiedDate < @reserveDate THEN 1 ELSE 0 END) ReserveExpired
FROM [Order] o --WITH(FORCESEEK) or WITH(INDEX=aaa)
WHERE o.ProductId = p.Id
) ca;
PRINT '***** Sol2 *****'
SELECT
p.Name
,p.Quantity
,ISNULL(q.Completed,0) Completed
,ISNULL(q.Reserved,0) Reserved
,ISNULL(q.ReserveExpired,0) ReserveExpired
,p.Quantity - ISNULL(q.Completed,0) - ISNULL(q.Reserved,0) Available
FROM Product p
LEFT MERGE JOIN --or LEFT JOIN
(
SELECT o.ProductId
,SUM(CASE WHEN o.Completed = 1 THEN 1 ELSE 0 END) Completed
,SUM(CASE WHEN o.Completed <> 1 AND o.ModifiedDate >= @reserveDate THEN 1 ELSE 0 END) Reserved
,SUM(CASE WHEN o.Completed <> 1 AND o.ModifiedDate < @reserveDate THEN 1 ELSE 0 END) ReserveExpired
FROM [Order] o
GROUP BY o.ProductId
) q ON p.Id = q.ProductId;
CREATE INDEX aaa
ON [Order](ProductId)
INCLUDE (Completed,ModifiedDate);
PRINT '***** Sol1 *****'
SELECT
p.Name
,p.Quantity
,ISNULL(ca.Completed,0) Completed
,ISNULL(ca.Reserved,0) Reserved
,ISNULL(ca.ReserveExpired,0) ReserveExpired
,p.Quantity - ISNULL(ca.Completed,0) - ISNULL(ca.Reserved,0) Available
FROM Product p
OUTER APPLY
(
SELECT
SUM(CASE WHEN o.Completed = 1 THEN 1 ELSE 0 END) Completed
,SUM(CASE WHEN o.Completed <> 1 AND o.ModifiedDate >= @reserveDate THEN 1 ELSE 0 END) Reserved
,SUM(CASE WHEN o.Completed <> 1 AND o.ModifiedDate < @reserveDate THEN 1 ELSE 0 END) ReserveExpired
FROM [Order] o --WITH(FORCESEEK) or WITH(INDEX=aaa)
WHERE o.ProductId = p.Id
) ca;
PRINT '***** Sol2 *****'
SELECT
p.Name
,p.Quantity
,ISNULL(q.Completed,0) Completed
,ISNULL(q.Reserved,0) Reserved
,ISNULL(q.ReserveExpired,0) ReserveExpired
,p.Quantity - ISNULL(q.Completed,0) - ISNULL(q.Reserved,0) Available
FROM Product p
LEFT MERGE JOIN --or LEFT JOIN
(
SELECT o.ProductId
,SUM(CASE WHEN o.Completed = 1 THEN 1 ELSE 0 END) Completed
,SUM(CASE WHEN o.Completed <> 1 AND o.ModifiedDate >= @reserveDate THEN 1 ELSE 0 END) Reserved
,SUM(CASE WHEN o.Completed <> 1 AND o.ModifiedDate < @reserveDate THEN 1 ELSE 0 END) ReserveExpired
FROM [Order] o
GROUP BY o.ProductId
) q ON p.Id = q.ProductId;