Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为所有日期和具有计数和类别的所有用户创建矩阵_Sql_Sql Server_Tsql - Fatal编程技术网

Sql 为所有日期和具有计数和类别的所有用户创建矩阵

Sql 为所有日期和具有计数和类别的所有用户创建矩阵,sql,sql-server,tsql,Sql,Sql Server,Tsql,我正在使用SQL Server 2012,并具有以下表格: CREATE TABLE [dbo].[Users]( [UserId] [bigint] NOT NULL ) CREATE TABLE [dbo].[CategoryIds]( [CategoryId] [int] NOT NULL ) CREATE TABLE [dbo].[DimDate]( [Year_Value] [int] NOT NULL, [Month_Value] [int] NOT

我正在使用SQL Server 2012,并具有以下表格:

CREATE TABLE [dbo].[Users](
    [UserId] [bigint] NOT NULL
)
CREATE TABLE [dbo].[CategoryIds](
    [CategoryId] [int] NOT NULL
)
CREATE TABLE [dbo].[DimDate](
    [Year_Value] [int] NOT NULL,
    [Month_Value] [int] NOT NULL
) 
CREATE TABLE [dbo].[TransactionsData](
    [TransactionId] [int] NOT NULL,
[UserId] [bigint] NOT NULL,
[CategoryId] [int] NOT NULL,
[Date] [datetime] NOT NULL
)
表中的数据如下所示:

Insert into [dbo].[Users]
select 1 union all
select 2 union all
select 3


Insert into [dbo].[CategoryIds]
select 1 union all
select 2 union all
select 5

insert into [dbo].[DimDate]
select 2015, 3 union all
select 2015,4

insert into [dbo].[TransactionsData]
select 1,1,1,'2015-03-01' union all
select 2,1,1,'2015-03-20' union all
select 3,2,5,'2015-03-02' union all
select 4,2,5,'2015-03-05'
我想要一个生成如下表的T-SQL代码:

CREATE TABLE [dbo].[Matrix](
[Year_Value] [int] NOT NULL,
[Month_Value] [int] NOT NULL,
[UserId] [bigint] NOT NULL,
[TransactionCount] [bigint] NOT NULL,
[1] [int] NOT NULL, -- category with id 1
[2] [int] NOT NULL, -- category with id 2
[5] [int] NOT NULL  -- category with id 5 etc
)
矩阵表包含每个用户每年和每月的记录,不管该用户当月是否有任何交易。如果没有事务,则年、月和用户ID仍然作为记录存在,但事务计数为0。这同样适用于类别:每个CategoryId都成为矩阵表的一列,并且在每列中都有一个计数,即每年、每月和每个用户属于每个类别的事务数。如果没有特定用户和特定类别的事务,则相应列中的值为0

我所尝试的:

select d.*, u.UserId, isnull(t.TransactionId,0) 
from [dbo].[DimDate] d 
outer apply (select UserId from [dbo].[Users]) u 
full outer join [dbo].[TransactionsData] t on u.UserId = t.UserId

鉴于上表中的数据,矩阵表中的数据如下所示:

INSERT INTO  [dbo].[Matrix]
SELECT 2015, 3, 1, 2, 2, 0, 0 UNION ALL 
SELECT 2015, 3, 2, 2, 0, 0, 2 UNION ALL 
SELECT 2015, 3, 3, 0, 0, 0, 0 UNION ALL
SELECT 2015, 4, 1, 0, 0, 0, 0 UNION ALL
SELECT 2015, 4, 2, 0, 0, 0, 0 UNION ALL
SELECT 2015, 4, 3, 0, 0, 0, 0
您可以使用以下方法执行此操作:


其思想是生成所有可能的
UserId
-
年值
-
月值
组合。然后,使用生成的组合,在
TransactionData
上执行
左连接

现在,要使
categoryId
显示为列,需要进行条件聚合。这是非动态的解决方案。这也是
PRINT@sql
命令的输出

SELECT
    a.Year_Value
    , a.Month_Value
    , a.UserId
    , COUNT(td.TransactionId) AS TransactionCount
    , SUM(CASE WHEN CategoryId = 1 THEN 1 ELSE 0 END) AS [1]
    , SUM(CASE WHEN CategoryId = 2 THEN 1 ELSE 0 END) AS [2]
    , SUM(CASE WHEN CategoryId = 5 THEN 1 ELSE 0 END) AS [5]
FROM (
    SELECT
        u.UserId, dd.Year_Value, m.Month_Value
    FROM(VALUES
        (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
    )m(Month_Value)
    CROSS JOIN(
        SELECT DISTINCT Year_Value FROM DimDate
    )dd
    CROSS JOIN Users u  
) AS a
LEFT JOIN TransactionsData td
    ON td.UserId = a.UserId
    AND MONTH(td.Date) = a.Month_Value
    AND YEAR(td.Date) = a.Year_Value
GROUP BY
    a.Year_Value, a.Month_Value, a.UserId
ORDER BY
    a.UserId, a.Year_Value, a.Month_Value

我尝试了以下方法:
select d.*,u.UserId,isnull(t.TransactionId,0)from[dbo]。[DimDate]d outer apply(select UserId from[dbo]。[Users])u full outer join[dbo]。[transactiondata]t on u.UserId=t.UserId
但是缺少一些记录。这样做的目的是获取所有记录,然后对交易和类别的计数进行透视。我在正确的轨道上吗?您能发布样本数据的预期结果吗?鉴于上表中的数据,
INSERT INTO[dbo]。[Matrix]选择2015,3,1,2,2,0,0联合所有选择2015,3,2,2,2,0,0,2联合所有选择2015,3,3,0,0,0联合所有选择2015,4,1,0,0,0联盟所有人选择2015,4,2,0,0,0,0联盟所有人选择2015,4,3,0,0,0,0,0
很高兴能提供帮助!如果您觉得我的回答对您有用,请随时接受。:-)
SELECT
    a.Year_Value
    , a.Month_Value
    , a.UserId
    , COUNT(td.TransactionId) AS TransactionCount
    , SUM(CASE WHEN CategoryId = 1 THEN 1 ELSE 0 END) AS [1]
    , SUM(CASE WHEN CategoryId = 2 THEN 1 ELSE 0 END) AS [2]
    , SUM(CASE WHEN CategoryId = 5 THEN 1 ELSE 0 END) AS [5]
FROM (
    SELECT
        u.UserId, dd.Year_Value, m.Month_Value
    FROM(VALUES
        (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
    )m(Month_Value)
    CROSS JOIN(
        SELECT DISTINCT Year_Value FROM DimDate
    )dd
    CROSS JOIN Users u  
) AS a
LEFT JOIN TransactionsData td
    ON td.UserId = a.UserId
    AND MONTH(td.Date) = a.Month_Value
    AND YEAR(td.Date) = a.Year_Value
GROUP BY
    a.Year_Value, a.Month_Value, a.UserId
ORDER BY
    a.UserId, a.Year_Value, a.Month_Value