【发布时间】:2022-01-20 21:00:00
【问题描述】:
我的 SQL 数据库中有四个表,即 MenuItems、Categories、Invoices 和 InvoiceDetails。现在我想要显示某个日期的菜单性能报告,即总数量和总金额
特定日期的每个菜单项。它在 where 子句中显示不带日期的所需结果,但不包括具有空值的菜单项。
这是我的存储过程:
CREATE PROCEDURE spGetMenuPerformanceByDay
@Date date,
@Terminal int
AS
BEGIN
SELECT
M.Name,
ISNULL(SUM(D.Amount), 0) AS Amount,
ISNULL(SUM(D.Qty), 0) AS Qty
FROM
MenuItems AS M
JOIN
Categories AS C ON C.Id = M.CategoryId
LEFT JOIN
InvoiceDetails AS D ON M.Id = D.ItemId
LEFT JOIN
Invoices I ON I.Id = d.InvoiceId
WHERE
@Terminal IN (I.TerminalId, C.TerminalId)
AND CONVERT(date, I.Time) = @Date
OR NULL IN (Amount, Qty)
GROUP BY
M.Name, M.Id, D.ItemId
ORDER BY
(Qty) DESC
END
该存储过程在 where 子句中添加 Date 时返回的结果:
| Item | Amount | Qty |
|---|---|---|
| KOFTA ANDA | 1950 | 3 |
| HOT N SOUR SOUP | 550 | 1 |
| CHICKEN CHOWMEIN | 250 | 1 |
| CHICKEN KORMA | 850 | 1 |
我想要的结果是,但在 where 子句中添加 Date 时没有得到它:
| Item | Amount | Qty |
|---|---|---|
| KOFTA ANDA | 1950 | 3 |
| HOT N SOUR SOUP | 550 | 1 |
| CHICKEN CHOWMEIN | 250 | 1 |
| CHICKEN KORMA | 850 | 1 |
| CRISPY CHICKEN | 0 | 0 |
| MEXICAN BURGER | 0 | 0 |
【问题讨论】:
-
Null in (Amount,Qty)永远不会是真的。测试列的唯一方法是 null 是is null -
我不想测试,而是添加具有空值的行。问题在于在 where 子句中添加日期,排除具有空值的行。
-
-
程序代码是高度特定于供应商的 - 所以请添加一个标签来指定您是否使用
mysql、postgresql、sql-server、oracle或db2- 或完全不同的东西。 -
看起来你缺少
OR的括号,而且NULL IN ...永远不会起作用,因为NULL不等于包括它自己在内的任何东西。最重要的是,CONVERT(date可能会导致性能问题。试试AND ((I.Time >= CAST(CAST(@Date AS date) AS datetime) AND I.Time < CAST(DATEADD(day, 1, CAST(@Date AS date) AS datetime))) OR Amount IS NULL OR Qty IS NULL)
标签: sql sql-server performance stored-procedures