使用SQL Server存储过程构建报表

时间:2012-10-12 10:51:34

标签: sql sql-server stored-procedures reporting

构建报告的最佳做法是什么,该报告显示来自多个表的数据,并且可以通过某些字段进行搜索,例如按日期搜索?

报告的结构如下:

                Today    Yesterday  Last 7 days     All
New Users         0         10        20           1000
Sold Products     11        21        31           25000

我能想到的只是使用存储过程和OUTPUT参数构建报表,它工作得非常好,但它在SQL Server端和应用程序中都是一项繁琐的工作。我只是不知道其他任何方式。

也许可以通过使用游标或使用不同的存储过程或其他技术来完成。你能指导我一个更好的方法吗?我感谢任何帮助。

这是我目前的做法

CREATE PROCEDURE sp_Statistics
    @DateFrom datetime = NULL, 
    @DateTo datetime = NULL,

    @UsersRegisteredToday int = 0 OUTPUT,
    @UsersRegisteredYesterday int = 0 OUTPUT, 
    @UsersRegisteredLastSevenDays int = 0 OUTPUT,
    @UsersRegisteredTotal int = 0 OUTPUT,
    @UsersRegisteredDate int = 0 OUTPUT,

    @SoldProductsToday int = 0 OUTPUT,
    @SoldProductsYesterday int = 0 OUTPUT, 
    @SoldProductsLastSevenDays int = 0 OUTPUT,
    @SoldProductsTotal int = 0 OUTPUT,
    @SoldProductsDate int = 0 OUTPUT
AS
BEGIN

--------------------- REGISTERED USERS -----------------------
IF (@DateFrom IS NOT NULL OR @DateTo IS NOT NULL)
    BEGIN
        SELECT @UsersRegisteredDate = COUNT(*)
        FROM [User] u
        WHERE DATEADD(DAY, DATEDIFF(D, 0, u.Date), 0) BETWEEN @DateFrom AND @DateTo
    END
ELSE IF @DateFrom IS NULL AND @DateTo IS NULL
    BEGIN
        SELECT @UsersRegisteredToday = COUNT(DISTINCT u.idUser)
        FROM [User] u
        LEFT JOIN [Order] e ON u.idUser = e.idUser
        WHERE DATEDIFF(d, GETDATE(), u.Date) = 0

        SELECT @UtilizadoresYesterday = COUNT(DISTINCT u.idUser)
        FROM [User] u
        LEFT JOIN [Order] e ON u.idUser = e.idUser
        WHERE DATEDIFF(d, GETDATE(), u.Date) = -1

        SELECT @UsersRegisteredLastSevenDays = COUNT(DISTINCT u.idUser)
        FROM [User] u
        LEFT JOIN [Order] e ON u.idUser = e.idUser
        WHERE DATEDIFF(d, GETDATE(), u.Date) >= -7

        SELECT @UsersRegisteredTotal = COUNT(DISTINCT u.idUser)
        FROM [User] u
        LEFT JOIN [Order] e ON u.idUser = e.idUser
    END

--------------------- SOLD PRODUCTS --------------------------
IF (@DateFrom IS NOT NULL OR @DateTo IS NOT NULL)
    BEGIN
        SELECT @SoldProductsDate = COUNT(*)
        FROM [Order] e
        WHERE e.idPaymentState = 2
              AND
              DATEADD(DAY, DATEDIFF(D, 0, e.Date), 0) BETWEEN @DateFrom AND @DateTo
    END
ELSE IF @DateFrom IS NULL AND @DateTo IS NULL
    BEGIN

        SELECT @SoldProductsToday = COUNT(*) 
        FROM [Order] e 
        LEFT JOIN [User] u ON e.idUser = u.idUser
        WHERE e.idPaymentState = 2 AND DATEDIFF(d, GETDATE(), e.Date) = 0

        SELECT @SoldProductsYesterday = COUNT(*)
        FROM [Order] e
        LEFT JOIN [User] u ON e.idUser = u.idUser
        WHERE e.idPaymentState = 2 AND DATEDIFF(d, GETDATE(), e.Date) = -1

        SELECT @SoldProductsLastSevenDays = COUNT(*)
        FROM [Order] e
        LEFT JOIN [User] u ON e.idUser = u.idUser
        WHERE e.idPaymentState = 2 AND DATEDIFF(d, GETDATE(), e.Date) >= -7

        SELECT @SoldProductsTotal = COUNT(*)
        FROM [Order] e
        LEFT JOIN [User] u ON e.idUser = u.idUser
        WHERE e.idPaymentState = 2
    END
END

3 个答案:

答案 0 :(得分:3)

您是否考虑过使用SSRS? SQL Reporting Services,它捆绑了SQL ..我在这里咆哮错误的树吗?

我会考虑使用它来创建报告,因为它是一个报告工具

您只需使用一些参数

编写数据'SELECT'

e.g。

SELECT SomeValue, SomeOtherValue FROM SomeTable WHERE SomeValue = @SomeParameter

参数是可配置的等等......你以前没有听说过/看过/使用它吗?

e.g。这是我们的一份报告 - 真的只需要一个小时来写这份报告......

one of our reports

答案 1 :(得分:3)

我不是使用输出参数,而是在sp中创建一个临时表并将数据插入到该表中,然后一旦所有数据都在那里进行选择。

如果您在应用程序中使用网格或者Charleh建议使用SSRS的更好选项,那么创建报告本身应该相当容易。然后,您可以将SSRS报告查看器嵌入到您的应用程序中。

答案 2 :(得分:1)

最好使用table-valued UDF

CREATE FUNCTION fn_Statistics
(
    @DateFrom datetime = NULL, 
    @DateTo datetime = NULL
)
RETURNS @Report TABLE(
    Today int,
    Yesterday,
    LastSevenDays,
    Total int,
    [Date] int)
AS    
BEGIN
--------------------- REGISTERED USERS -----------------------
IF (@DateFrom IS NOT NULL OR @DateTo IS NOT NULL)
    BEGIN
        INSERT @Report
        SELECT 0,0,0,0,COUNT(*)
        FROM [User] u
        WHERE DATEADD(DAY, DATEDIFF(D, 0, u.Date), 0) BETWEEN @DateFrom AND @DateTo;
--------------------- SOLD PRODUCTS --------------------------        
        INSERT @Report
        SELECT 0,0,0,0,COUNT(*)
        FROM [Order] e
        WHERE e.idPaymentState = 2
              AND
              DATEADD(DAY, DATEDIFF(D, 0, e.Date), 0) BETWEEN @DateFrom AND @DateTo;

    END
    ELSE IF @DateFrom IS NULL AND @DateTo IS NULL
    BEGIN
        DECLARE @UsersRegisteredToday int,
                @UsersRegisteredYesterday int,
                @UsersRegisteredLastSevenDays int,
                @UsersRegisteredTotal int;

        SELECT @UsersRegisteredToday = COUNT(DISTINCT u.idUser)
        FROM [User] u
        LEFT JOIN [Order] e ON u.idUser = e.idUser
        WHERE DATEDIFF(d, GETDATE(), u.Date) = 0

        SELECT @UtilizadoresYesterday = COUNT(DISTINCT u.idUser)
        FROM [User] u
        LEFT JOIN [Order] e ON u.idUser = e.idUser
        WHERE DATEDIFF(d, GETDATE(), u.Date) = -1

        SELECT @UsersRegisteredLastSevenDays = COUNT(DISTINCT u.idUser)
        FROM [User] u
        LEFT JOIN [Order] e ON u.idUser = e.idUser
        WHERE DATEDIFF(d, GETDATE(), u.Date) >= -7

        SELECT @UsersRegisteredTotal = COUNT(DISTINCT u.idUser)
        FROM [User] u
        LEFT JOIN [Order] e ON u.idUser = e.idUser

        INSERT @Report VALUES(@UsersRegisteredToday,
                              @UsersRegisteredYesterday,
                              @UsersRegisteredLastSevenDays,
                              @UsersRegisteredTotal,
                              0);
        --------------------- SOLD PRODUCTS --------------------------

        DECLARE @SoldProductsToday int,
                @SoldProductsYesterday int,
                @SoldProductsLastSevenDays int,
                @SoldProductsTotal int;

        SELECT @SoldProductsToday = COUNT(*) 
        FROM [Order] e 
        LEFT JOIN [User] u ON e.idUser = u.idUser
        WHERE e.idPaymentState = 2 AND DATEDIFF(d, GETDATE(), e.Date) = 0

        SELECT @SoldProductsYesterday = COUNT(*)
        FROM [Order] e
        LEFT JOIN [User] u ON e.idUser = u.idUser
        WHERE e.idPaymentState = 2 AND DATEDIFF(d, GETDATE(), e.Date) = -1

        SELECT @SoldProductsLastSevenDays = COUNT(*)
        FROM [Order] e
        LEFT JOIN [User] u ON e.idUser = u.idUser
        WHERE e.idPaymentState = 2 AND DATEDIFF(d, GETDATE(), e.Date) >= -7

        SELECT @SoldProductsTotal = COUNT(*)
        FROM [Order] e
        LEFT JOIN [User] u ON e.idUser = u.idUser
        WHERE e.idPaymentState = 2

        INSERT @Report VALUES(@SoldProductsToday,
                              @SoldProductsYesterday,
                              @SoldProductsLastSevenDays,
                              @SoldProductsTotal,
                              0);
    END
    RETURN
 END