2009-01-16 58 views
2

我正在嘗試在存儲過程中執行一個很好的SQL語句。對結果集執行計數(*)

我看了看兩天之間發生事件的天數問題。 我的例子是銷售訂單:對於這個月,我們有多少天有銷售訂單?

假設這個設置:

CREATE TABLE `sandbox`.`orders` (
    `year` int, 
    `month` int, 
    `day` int, 
    `desc` varchar(255) 
) 

INSERT INTO orders (year, month, day, desc) 
VALUES (2009,1,1, 'New Years Resolution 1') 
     ,(2009,1,1, 'Promise lose weight') 
     ,(2009,1,2, 'Bagel') 
     ,(2009,1,12, 'Coffee to go') 

對於這種在數據結果應該是3,因爲已經三天銷售。 我找到的最佳解決方案如下。

但是,製作一張臨時表格,然後將其刪除,然後將其刪除。它在一個聲明中「應該」是可能的。

任何人誰得到了「更好」的解決方案,然後我?

/L

SELECT [Year], [Month], [Day] 
INTO #Some_Days 
FROM Quarter 
WHERE Start >= '2009-01-01' AND [End] < '2009-01-16' 
GROUP BY [Year], [Month], [Day] 

SELECT count(*) from #Some_Days 

回答

6

道歉,如果我誤解了問題,但也許你可以做這樣的事情,作爲一個選項:

SELECT COUNT(*) FROM 
    (SELECT DISTINCT(SomeColumn) 
     FROM MyTable 
     WHERE Something BETWEEN 100 AND 500 
     GROUP BY SomeColumn) MyTable 

...繞過臨時表的創建和處理?

1

如何:

SELECT COUNT(DISTINCT day) FROM orders 
WHERE (year, month) = (2009, 1); 

其實,我不知道,如果TSQL支持元組比較,但你的想法。

COUNT(DISTINCT expr)是標準的SQL,應該可以在任何地方工作。

+0

那(年,月)是如何工作的?我從來沒有見過。 – 2009-01-17 00:01:06

+0

它應該相當於:(year = 2009 AND month = 1)。但我永遠不會記得哪些RDBMS品牌支持它,哪些不支持。有些不能很好地優化它。可能最好避免。 – 2009-01-17 00:03:00

0
SELECT [Year], [Month], [Day] 
FROM Quarter 
WHERE Start >= '2009-01-01' AND [End] < '2009-01-16' 
GROUP BY [Year], [Month], [Day] 
COMPUTE COUNT(*) 
2

有兩個基本的選項,我可以看到。一種方法是將所有內容分組在一個子查詢中,然後對這些不同的行進行計數(Christian Nunciato的答案)。其次是組合多個字段並計算該組合值的不同值。

在這種情況下,以下公式將三個字段轉換爲單個日期時間。

DATEADD(YEAR, [Quarter].Year, DATEADD(MONTH, [Quarter].Month, DATEADD(DAY, [Quarter].DAY, 0), 0), 0) 

因此,COUNT(DISTINCT [配方])會給你所需要的答案。

SELECT 
    COUNT(DISTINCT DATEADD(YEAR, [Quarter].Year, DATEADD(MONTH, [Quarter].Month, DATEADD(DAY, [Quarter].DAY, 0), 0), 0)) 
FROM 
    Quarter 
WHERE 
    [Quarter].Start >= '2009-01-01' 
    AND [Quarter].End < '2009-01-16' 

我通常使用子查詢路線,但是這取決於你在做什麼,索引,表的大小,公式等的簡單性,這可以更快......

民主黨。

1

您應該使用嵌套的Select語句。內部一個應該包含group by子句,外部應該包含它。我認爲「Christian Nunciato」已經幫助過你。

Select Count(1) As Quantity 
From 
( 
    SELECT [Year], [Month], [Day] 
    INTO #Some_Days 
    FROM Quarter 
    WHERE Start >= '2009-01-01' AND [End] < '2009-01-16' 
    GROUP BY [Year], [Month], [Day] 
) AS InnerResultSet