如果日期不在日期维度表中,则显示带0的度量值

时间:2015-02-02 16:56:51

标签: sql sql-server date join measure

我很难在事实表和日期维度表之间建立连接,因为我想显示日期不在维度表中的记录。

示例:当我尝试此查询时,我在01:00没有记录2014-09-08,因为事实表中没有包含这些过滤器的记录。

select *
from FCT_SCAN scan
left join dim_date dt
on cast ( scan.DATE_HEURE as date ) = dt.DATE
and cast(cast ( scan.DATE_HEURE as time(0)) as varchar(5)) = CAST(dt.heure as varchar(5))
where CAST(scan.DATE_HEURE as DATE) = '2014-08-09'
and tranche_1h = '01:00:00'
order by heure

如果DATE_HEURE字段不在维度表中,我想显示字段为NULL或0的记录。

编辑1:
首先,我使用好的前缀重写我的初始查询,以便更好地理解。

select *
from FCT_SCAN scan
left join dim_date dt
on cast ( scan.DATE_HEURE as date ) = dt.DATE
and cast(cast ( scan.DATE_HEURE as time(0)) as varchar(5)) = CAST(dt.heure as varchar(5))
where CAST(scan.DATE_HEURE as date) = '2014-08-09'
and dt.tranche_1h = '01:00:00'
order by dt.heure

我的问题如下:我正在搜索一个特殊的条件连接,它允许我将我的事实表与Cognos中的日期维度表链接起来。这个联接必须允许我显示"空"记录维度表中的某些日期时间是否在事实表中,如果存在日期时间,则记录在事实表中。

更新:这是DIM_DATE的CREATE TABLE和SELECT脚本。

CREATE TABLE [dbo].[DIM_DATE](
    [DATE_HEURE] [datetime] NOT NULL,
    [ANNEE] [int] NULL,
    [MOIS] [int] NULL,
    [JOUR] [int] NULL,
    [DATE] [date] NULL,
    [JOUR_SEM_DATE] [varchar](10) NULL,
    [NUM_JOUR_SEM_DATE] [int] NULL,
    [HEURE] [time](0) NULL,
    [TRANCHE_1H] [time](0) NULL,
    [TRANCHE_DEMIH] [time](0) NULL,
    [TRANCHE_QUARTH] [time](0) NULL,
    [TRANCHE_10M] [time](0) NULL,
 CONSTRAINT [PK_DIM_DATE] PRIMARY KEY CLUSTERED 
(
    [DATE_HEURE] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

DATE_HEURE  ANNEE   MOIS    JOUR    DATE    JOUR_SEM_DATE   NUM_JOUR_SEM_DATE   HEURE   TRANCHE_1H  TRANCHE_DEMIH   TRANCHE_QUARTH  TRANCHE_10M
2013-01-01 00:00:00.000 2013    1   1   2013-01-01  Tuesday 3   00:00:00    00:00:00    00:00:00    00:00:00    00:00:00
2013-01-01 00:01:00.000 2013    1   1   2013-01-01  Tuesday 3   00:01:00    00:00:00    00:00:00    00:00:00    00:00:00
2013-01-01 00:02:00.000 2013    1   1   2013-01-01  Tuesday 3   00:02:00    00:00:00    00:00:00    00:00:00    00:00:00
2013-01-01 00:03:00.000 2013    1   1   2013-01-01  Tuesday 3   00:03:00    00:00:00    00:00:00    00:00:00    00:00:00
2013-01-01 00:04:00.000 2013    1   1   2013-01-01  Tuesday 3   00:04:00    00:00:00    00:00:00    00:00:00    00:00:00
2013-01-01 00:05:00.000 2013    1   1   2013-01-01  Tuesday 3   00:05:00    00:00:00    00:00:00    00:00:00    00:00:00
2013-01-01 00:06:00.000 2013    1   1   2013-01-01  Tuesday 3   00:06:00    00:00:00    00:00:00    00:00:00    00:00:00
2013-01-01 00:07:00.000 2013    1   1   2013-01-01  Tuesday 3   00:07:00    00:00:00    00:00:00    00:00:00    00:00:00
2013-01-01 00:08:00.000 2013    1   1   2013-01-01  Tuesday 3   00:08:00    00:00:00    00:00:00    00:00:00    00:00:00
2013-01-01 00:09:00.000 2013    1   1   2013-01-01  Tuesday 3   00:09:00    00:00:00    00:00:00    00:00:00    00:00:00

此表中存储的2013-01-01 00:00:00至2017-12-31 23:59:00分为1分钟。 我们在FCT_SCAN中的DATE_HEURE字段和DIM_DATE字段之间建立连接。

这是FCT_SCAN中的DATE_HEURE字段:

DATE_HEURE
2014-10-17 21:39:27.000
2014-10-17 21:44:37.000
2014-10-17 23:14:05.000
2014-10-17 23:14:01.000
2014-10-17 21:40:09.000
2014-10-17 21:44:25.000
2014-10-17 21:41:41.000
2014-10-17 21:41:51.000
2014-10-17 21:48:12.000
2014-10-17 23:09:32.000

我没有向您展示FCT_SCAN的所有字段,因为大约有180个字段...

编辑2:
有关信息,如果01:00和01:30之间没有数据,我所需的输出如下所示:

DATE_HEURE   FIELD0   FIELD1   FIELD2   MEASURE0   MEASURE1   MEASURE2

2015-02-03 00:00:00   XXX   XXX   XXX   5   42   23
2015-02-03 00:30:00   XXX   XXX   XXX   5   42   23
2015-02-03 01:00:00   NULL   NULL   NULL   0   0   0
2015-02-03 01:30:00   NULL   NULL   NULL   0   0   0
2015-02-03 02:00:00   XXX   XXX   XXX   5   42   23
2015-02-03 02:30:00   XXX   XXX   XXX   5   42   23

2 个答案:

答案 0 :(得分:1)

尝试外部申请:

select *
from FCT_SCAN scan
OUTER APPLY( select * from dim_date dt
where cast ( scan.DATE_HEURE as date ) = dt.DATE
and cast(cast ( scan.DATE_HEURE as time(0)) as varchar(5)) = CAST(dt.heure as varchar(5))) o
where CAST(scan.DATE_HEURE as DATE) = '2014-08-09'
and tranche_1h = '01:00:00'
order by heure

如果tranche_1h列来自dim_date,请使用:

select *
from FCT_SCAN scan
OUTER APPLY( select * from dim_date dt
where cast ( scan.DATE_HEURE as date ) = dt.DATE
and cast(cast ( scan.DATE_HEURE as time(0)) as varchar(5)) = CAST(dt.heure as varchar(5)) and tranche_1h = '01:00:00') o
where CAST(scan.DATE_HEURE as DATE) = '2014-08-09'
order by heure

答案 1 :(得分:0)

你可能只是因为需要时间而不是第二次而遇到问题?

select *
from fct_scan scan
RIGHT JOIN dim_date dt 
on dt.Date = cast ( scan.DATE_HEURE as date )
and  cast(cast(cast(scan.DATE_HEURE as time(0)) as varchar(5)) as time) = dt.heure
order by heure