如何将太多的SQL调用整合为一个

时间:2019-06-04 10:54:07

标签: sql sql-server tsql sql-server-2012

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
....

2 个答案:

答案 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;