15

SQL 2005テーブルがあり、次の形式でOrdersと呼びます。

OrderID, OrderDate,  OrderAmount
1,       25/11/2008, 10
2,       25/11/2008, 2
3,       30/1002008, 5

次に、過去7日間の各日の注文額を示すレポートテーブルを作成する必要があります。

Day,        OrderCount, OrderAmount
25/11/2008, 2,          12
26/11/2008, 0,          0 
27/11/2008, 0,          0 
28/11/2008, 0,          0
29/11/2008, 0,          0
30/11/2008, 1,          5

通常これを生成するSQLクエリ:

select count(*), sum(OrderAmount)
    from Orders
    where OrderDate>getdate()-7
    group by datepart(day,OrderDate)

注文がない日をスキップするという問題があります:

Day,        OrderCount, OrderAmount
25/11/2008, 2,          12
30/11/2008, 1,          5

通常、タリーテーブルとそこの行に対する外部結合を使用してこれを修正しますが、これに対するより単純でより効率的なソリューションを本当に探しています。レポートクエリの一般的な要件のように思われるため、これにはすでにいくつかの洗練されたソリューションが利用可能であるはずです。

したがって、1。この結果は、集計テーブルを使用せずに単純なクエリから取得できますか?

2.いいえの場合、この集計テーブルを(確実に)オンザフライで作成できますか(CTEを使用して集計テーブルを作成できますが、再帰スタックでは100行に制限されます)。

4

6 に答える 6

10

SQL は日付を「スキップ」していません...実際にテーブルにあるデータに対してクエリが実行されるためです。したがって、テーブルに 1 月 14 日の DATE がない場合、なぜ SQL は結果を表示するのでしょうか :)

あなたがする必要があるのは、一時テーブルを作成し、それにJOINすることです。

CREATE TABLE #MyDates ( TargetDate DATETIME )
INSERT INTO #MyDates VALUES CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 0, 101))
INSERT INTO #MyDates VALUES CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 1, 101))
INSERT INTO #MyDates VALUES CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 2, 101))
INSERT INTO #MyDates VALUES CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 3, 101))
INSERT INTO #MyDates VALUES CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 4, 101))
INSERT INTO #MyDates VALUES CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 5, 101))
INSERT INTO #MyDates VALUES CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 6, 101))
INSERT INTO #MyDates VALUES CONVERT(DATETIME, CONVERT(VARCHAR, GETDATE() - 7, 101))

SELECT CONVERT(VARCHAR, TargetDate, 101) AS Date, COUNT(*) AS OrderCount
FROM dbo.Orders INNER JOIN #MyDates ON Orders.Date = #MyDates.TargetDate
GROUP BY blah blah blah (you know the rest)

ほら!

于 2008-11-30T22:31:57.767 に答える
2

私は同じ問題を抱えていましたが、これが私がそれを解決した方法です:

SELECT datename(DW,nDays) TimelineDays, 
    Convert(varchar(10), nDays, 101) TimelineDate,
    ISNULL(SUM(Counter),0) Totals 
FROM (Select GETDATE() AS nDays
    union Select GETDATE()-1
    union Select GETDATE()-2
    union Select GETDATE()-3
    union Select GETDATE()-4
    union Select GETDATE()-5
    union Select GETDATE()-6) AS tDays

Left Join (Select * From tHistory Where Account = 1000) AS History
            on (DATEPART(year,nDays) + DATEPART(MONTH,nDays) + DATEPART(day,nDays)) = 
            (DATEPART(year,RecordDate) + DATEPART(MONTH,RecordDate) + DATEPART(day,RecordDate)) 
GROUP BY nDays
ORDER BY nDays DESC

出力は次のとおりです。

TimelineDays,   TimelineDate,     Totals

Tuesday         10/26/2010        0
Monday          10/25/2010        6
Sunday          10/24/2010        3
Saturday        10/23/2010        2
Friday          10/22/2010        0
Thursday        10/21/2010        0
Wednesday       10/20/2010        0
于 2010-10-26T05:37:39.277 に答える
1

SQL Serverが一時テーブルを処理する方法に応じて、一時テーブルを作成し、関心のある7つ(または8つでしたか?)の日付を入力するように、多かれ少なかれ簡単に調整できます。その後、それを集計テーブルとして使用できます。私が知っているよりクリーンな方法はありません。テーブルに存在するデータ、またはテーブルまたはテーブルのセットに存在するデータから派生できるデータのみを選択できます。Ordersテーブルに表示されていない日付がある場合、Ordersテーブルからそれらの日付を選択することはできません。

于 2008-11-30T22:24:19.590 に答える
1
CREATE PROCEDURE [dbo].[sp_Myforeach_Date]
    -- Add the parameters for the stored procedure here
    @SatrtDate as DateTime,
    @EndDate as dateTime,
    @DatePart as varchar(2),
    @OutPutFormat as int 
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    Declare @DateList Table
    (Date varchar(50))

    WHILE @SatrtDate<= @EndDate
    BEGIN
    INSERT @DateList (Date) values(Convert(varchar,@SatrtDate,@OutPutFormat))
    IF Upper(@DatePart)='DD'
    SET @SatrtDate= DateAdd(dd,1,@SatrtDate)
    IF Upper(@DatePart)='MM'
    SET @SatrtDate= DateAdd(mm,1,@SatrtDate)
    IF Upper(@DatePart)='YY'
    SET @SatrtDate= DateAdd(yy,1,@SatrtDate)
    END 
    SELECT * FROM @DateList
END

このコードを入れて、このようにSPを呼び出すだけです

exec sp_Myforeach_Date @SatrtDate='03 Jan 2010',@EndDate='03 Mar 2010',@DatePart='dd',@OutPutFormat=106

ありがとう * Suvabrata Roy ICRA Online Ltd. コルカタ*

于 2010-12-23T13:37:30.883 に答える
1

ゼロの値を表示したい場合は、次のクエリを入力します。

select count(*), sum(OrderAmount)
from Orders
where OrderDate>getdate()-7
  and sum(OrderAmount) > 0 or sum(OrderAmount) = 0
group by datepart(day,OrderDate)
于 2010-08-21T20:12:53.323 に答える
0

この日付テーブルは他のクエリでも頻繁に使用するので、永続的なテーブルにして、年に 1 回新年の日付を追加するジョブを作成することをお勧めします。

于 2008-12-01T22:07:19.173 に答える