vb.net桌面应用程序必须在SQL Server(2012)上进行数百次此类调用。声明是在应用程序中编写的,并且需要数据库中数百次(有时甚至数千次)的时间。
我一直在寻找一种将调用综合为一个SQL语句或存储过程的方法。
一个语句与另一个语句之间的区别是“ day”变量(在示例代码中为“ 20190724”),该变量在每次调用时增加一天。
SELECT SUM(table1.qta)
FROM table1
WHERE (table1.id = 35)
AND ('20190724' BETWEEN table1.date1 AND table1.date2)
预期结果将为2列:
day1 SumQta1
day2 SumQta2
day3 SumQta3
....
答案 0 :(得分:2)
您应该做的就是改变方法。
无需单独查询每天的总和,而是创建一个用户定义的表类型来保存日期,然后使用该表类型将表值参数传递给数据库。
然后使用sum和按日期分组来查询连接到变量的表。
您的SQL应该看起来像这样:
CREATE TYPE dbo.DatesList
(
Date Date NOT NULL PRIMARY KEY
);
CREATE PROCEDURE GetSums
(
@Dates dbo.DatesList readonly
)
AS
SELECT Dates.Date, sum(table1.qta)
FROM table1
JOIN @Dates As Dates
ON Dates.Date BETWEEN table1.date1 AND table1.date2
WHERE table1.id = 35
GROUP BY Dates.Date
关于如何使用Vb.Net中的表值参数-嗯,这首先取决于您如何连接到数据库。我敢肯定,这里有大量的资源可以在stackoverflow上使用,也可以在网络上找到有关该部分的帮助。
答案 1 :(得分:0)
好吧,您可以根据需要在程序中构建一个VALUES
子句。然后左联接表并进行聚合以获得总和。返回您的应用程序,然后您就可以每天迭代结果。
SELECT d.day,
coalesce(sum(t.qta)) qta
FROM (VALUES ('20190101'),
('20190102'),
...) d (day)
LEFT JOIN table1 t
ON t.id = 35
AND d.day BETWEEN t.date1
AND t.date2
GROUP BY d.day
ORDER BY d.day;
另一种选择是使用递归CTE从最小值和最大值生成天数,然后对其进行联接,再次进行聚合以求和。
WITH
d (day)
AS
(
SELECT convert(date, '20190101') day
UNION ALL
SELECT dateadd(day, 1, day)
FROM d
WHERE dateadd(day, 1, day) <= convert(date, '20190131')
)
SELECT d.day,
coalesce(sum(t.qta)) qta
FROM d
LEFT JOIN table1 t
ON t.id = 35
AND d.day BETWEEN t.date1
AND t.date2
GROUP BY d.day
ORDER BY d.day;