Sql server 用外键填充事实表

Sql server 用外键填充事实表,sql-server,ssis,ssas,Sql Server,Ssis,Ssas,我正在从事一个项目,需要使用SSA分析Apache日志。我已经将数据加载到临时表中。我创建了维度表主键和attibute_名称,为每个维度表和fact_属性创建了空事实表外键,并在它们之间创建了关系。然后,我使用 INSERT INTO DimIP (IP) SELECT DISTINCT RemoteHostName FROM tmp ……等等 现在我需要用外键填充事实表,但我不知道如何使用单个查询来实现这一点。我试过这样的方法: INSERT INTO Facts (DimDateID,

我正在从事一个项目,需要使用SSA分析Apache日志。我已经将数据加载到临时表中。我创建了维度表主键和attibute_名称,为每个维度表和fact_属性创建了空事实表外键,并在它们之间创建了关系。然后,我使用

INSERT INTO DimIP (IP) SELECT DISTINCT RemoteHostName FROM tmp
……等等

现在我需要用外键填充事实表,但我不知道如何使用单个查询来实现这一点。我试过这样的方法:

INSERT INTO Facts (DimDateID, DimIPID, DimRefererID, DimRequestID, DimStatusCodeID, DimUserAgentID)
SELECT DimDate.ID WHERE (DimDate.Data = tmp.DateTime)
SELECT DimIP.ID WHERE (DimIP.IP = tmp.RemoteHostName)
SELECT DimReferer.ID WHERE (DimReferer.Referer = tmp.Referer)
SELECT DimRequest.ID WHERE (DimRequest.Request = tmp.Request)
SELECT DimStatusCode.ID WHERE (DimStatusCode.StatusCode = tmp.StatusCode)
SELECT DimUserAgent.ID WHERE (DimUserAgent.UserAgent = tmp.UserAgent)
INSERT INTO Facts (DimDateID)
SELECT DimDate.ID WHERE (DimDate.Data = tmp.DateTime)
但它不起作用,它说插入列表包含的项目比选择列表少,可能我不能使用这种语法

我试着一个接一个地做,就像这样:

INSERT INTO Facts (DimDateID, DimIPID, DimRefererID, DimRequestID, DimStatusCodeID, DimUserAgentID)
SELECT DimDate.ID WHERE (DimDate.Data = tmp.DateTime)
SELECT DimIP.ID WHERE (DimIP.IP = tmp.RemoteHostName)
SELECT DimReferer.ID WHERE (DimReferer.Referer = tmp.Referer)
SELECT DimRequest.ID WHERE (DimRequest.Request = tmp.Request)
SELECT DimStatusCode.ID WHERE (DimStatusCode.StatusCode = tmp.StatusCode)
SELECT DimUserAgent.ID WHERE (DimUserAgent.UserAgent = tmp.UserAgent)
INSERT INTO Facts (DimDateID)
SELECT DimDate.ID WHERE (DimDate.Data = tmp.DateTime)
但有时它会说其他列不能为NULL,例如DimUserAgentID,所以查询失败,有时它会执行查询,表示806000行受影响,但没有插入任何内容


我将感谢您的帮助,因为我已经扯掉了一半头发,不知道如何用维度表中的外键填充事实表。

我相信您需要做的是在查询中引用其他表。下面我使用tmp作为查询的主要驱动程序,然后尝试根据您提供的逻辑查找结果ID。这些查找是通过左外部联接进行的,这意味着关系可能不存在,在这种情况下,NULL将进入事实表。如果您希望过滤掉命中事实表的行,请用一个内部联接替换所有出现的行。我还假设您的表都在dbo模式中

INSERT INTO
    dbo.Facts 
(
    DimDateID
,   DimIPID
,   DimRefererID
,   DimRequestID
,   DimStatusCodeID
,   DimUserAgentID
)
SELECT
    DimDate.ID 
,   DimIP.ID 
,   DimReferer.ID
,   DimRequest.ID 
,   DimStatusCode.ID
,   DimUserAgent.ID 
FROM
    TMP T
    LEFT OUTER JOIN
        dbo.DimDate 
        ON DimDate.Data = T.DateTime
    LEFT OUTER JOIN
        dbo.DimIP
        ON DimIP.IP = T.RemoteHostName
    LEFT OUTER JOIN
        dbo.DimReferer
        ON DimReferer.Referer = T.Referer
    LEFT OUTER JOIN
        dbo.DimRequest
        ON DimRequest.Request = T.Request
    LEFT OUTER JOIN
        dbo.DimStatusCode
        ON DimStatusCode.StatusCode = T.StatusCode
    LEFT OUTER JOIN
        dbo.DimUserAgent
        ON DimUserAgent.UserAgent = T.UserAgent

最后,您似乎遗漏了一些可测量的内容,除非您只是在计算事实表中的行。

我相信您需要做的是在查询中引用那些其他表。下面我使用tmp作为查询的主要驱动程序,然后尝试根据您提供的逻辑查找结果ID。这些查找是通过左外部联接进行的,这意味着关系可能不存在,在这种情况下,NULL将进入事实表。如果您希望过滤掉命中事实表的行,请用一个内部联接替换所有出现的行。我还假设您的表都在dbo模式中

INSERT INTO
    dbo.Facts 
(
    DimDateID
,   DimIPID
,   DimRefererID
,   DimRequestID
,   DimStatusCodeID
,   DimUserAgentID
)
SELECT
    DimDate.ID 
,   DimIP.ID 
,   DimReferer.ID
,   DimRequest.ID 
,   DimStatusCode.ID
,   DimUserAgent.ID 
FROM
    TMP T
    LEFT OUTER JOIN
        dbo.DimDate 
        ON DimDate.Data = T.DateTime
    LEFT OUTER JOIN
        dbo.DimIP
        ON DimIP.IP = T.RemoteHostName
    LEFT OUTER JOIN
        dbo.DimReferer
        ON DimReferer.Referer = T.Referer
    LEFT OUTER JOIN
        dbo.DimRequest
        ON DimRequest.Request = T.Request
    LEFT OUTER JOIN
        dbo.DimStatusCode
        ON DimStatusCode.StatusCode = T.StatusCode
    LEFT OUTER JOIN
        dbo.DimUserAgent
        ON DimUserAgent.UserAgent = T.UserAgent

最后,您似乎遗漏了一些可测量的内容,除非您只是在计算事实表中的行数。

谢谢,效果非常好。这正是我需要的。我添加了BytesSent,因为度量和事实表可以完美地填充。谢谢,工作非常出色。这正是我需要的。我添加了BytesSent作为度量和事实表的完美填充。