2013-12-13 36 views
0

早上,所有的,迭代存储在一组日期

我正在寻找解决以下问题的有效方法: (请注意,我已经简化和更改的实际问题;然而,不应该反思那我基本上找)

,如果我想,以确定由特定公司拥有的每个Store交易,按日期分组的数量的结果,我已经运行下面的查询:

Select 
date_of_transaction 
,store 
,COUNT(*) 
from transactions t1 
group by date_of_transaction,store 
order by date_of_transaction 

但是,这种查询是不够的,因为它不返回storesdates如果交易的数量等于“0”

举例来说,如果没有通过store A1/Oct/2012 COMMITED,该行将任何交易从我的结果集中丢失。

这就是为什么,我想在过去的一年365天内强制执行,然后为每个Date显示每个Store。 换句话说,如果该公司拥有3家店,我需要3个纪录为今年的每一天,即使交易数量为“0”:

Date  Store  Number 
1/1/2012 A   1 
1/1/2012 B   0 
1/1/2012 C   3 
2/1/2012 A   1 
2/1/2012 B   2 
2/1/2012 C   0 
3/1/2012 A   1 
3/1/2012 B   0 
3/1/2012 C   0 

我有一个日历表,我有过去'联盟'的商店和迫使他们,但它必须是一个更好的方式来做到这一点。

问候 基里尔

回答

1

这样的事情,应该做你想要什么(你需要立足查询离您的日历和存储表,得到输出中的所有日期和所有的商店,然后LEFT JOIN交易表):

SELECT Calendar.Date, Stores.Store, COUNT(T1.transaction_id) AS Number 
FROM Calendar, Stores 
LEFT JOIN Transactions T1 ON T1.date_of_transaction = Calendar.date 
    AND T1.store = Stores.store 
GROUP BY Calendar.Date, Stores.Store 
+0

我无法识别日历和商店表之间的任何关系。 –

+0

那又如何?上面的查询不依赖于这两者之间的关系。它执行笛卡尔连接(以便您可以获取日历表中每个记录的Stores表中的每条记录)。它仅依赖于“事务”表和“商店”表之间以及“事务”表和“日历”表之间的关系。 – Dan

+0

没关系,我已经加入了它们之间的isnull(vw.Store_Start_Date,'19000101')和ISNULL(vw.Store_End_Date,GETDATE())之间的cal_daydate。谢谢你的帮助。 –

1

为什么不使用公用表表达式来计算不同的商店和日期。

下面是一个包含上述数据的测试表。

-- 
-- My database 
-- 

-- Play in temp 
use tempdb; 
go 

-- Create a table 
CREATE TABLE my_transactions 
(
    my_id INT identity(1, 1) primary key, 
    my_date DATETIME, 
    my_store CHAR(1), 
    my_sale MONEY 
); 

-- Insert some data 
INSERT INTO my_transactions (my_date, my_store, my_sale) 
VALUES 
('1/1/2012', 'A', 100), 
('1/1/2012', 'C', 100), 
('1/1/2012', 'C', 100), 
('1/1/2012', 'C', 100), 
('2/1/2012', 'A', 200), 
('2/1/2012', 'B', 200), 
('2/1/2012', 'B', 200), 
('3/1/2012', 'A', 300); 

-- Show the data 
SELECT * FROM my_transactions; 

enter image description here

我将使用符合表观,努力营造月份开始日期,存储和创建报表。

-- 
-- My report query 
-- 
; 
WITH cteMonths (my_number, my_date) AS 
(
    SELECT 
     ROW_NUMBER() OVER(ORDER BY a.name) AS my_number, 
     DATEADD(M, ROW_NUMBER() OVER(ORDER BY a.name) - 1, '2012-01-01') as my_date 
    FROM 
     sys.objects a 
    CROSS JOIN 
     sys.objects b 
), 
cteStores (my_store) as 
(
    SELECT DISTINCT my_store FROM my_transactions 
) 
SELECT 
    MS.my_date, 
    MS.my_store, 
    COUNT(T.my_id) as my_total 
FROM 
    (SELECT * FROM cteMonths CROSS JOIN cteStores WHERE my_number < 4) MS 
LEFT JOIN 
    my_transactions AS T ON MS.my_date = T.my_date and MS.my_store = T.my_store 
GROUP BY 
    MS.my_date, 
    MS.my_store 
ORDER BY 
    MS.my_date, 
    MS.my_store 
GO 

enter image description here