【问题标题】:Display lines with 0 for measures if date not in date dimension table如果日期不在日期维度表中,则为度量显示 0 行
【发布时间】:2015-02-02 16:56:50
【问题描述】:

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

示例:我在 01:00 尝试此查询时没有 2014 年 9 月 8 日的记录,因为事实表中没有使用这些过滤器的记录。

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 年 1 月 1 日 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

【问题讨论】:

  • tranche_1h 属于哪个表?
  • 你应该考虑重组你的表,这样你就可以实现外键。
  • 您的意思是 fact 表中没有该小时的数据吗?不知道为什么它应该从 dimension 表中丢失。如果即使事实表中没有数据也想包含维度表中的行,则左连接是向后的。另外,请在 all 列前加上表别名,这样人们就不必猜测哪些列来自哪个表。
  • 我还是不明白。但它看起来像你的条件 and dt.tranche_1h = '01:00:00' 在 where 部分将过滤掉任何不符合条件的行。由于您使用的是左连接,因此将此条件移动到连接部分以获得所需的结果。

标签: sql sql-server date join measure


【解决方案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

【讨论】:

  • 对不起,它不起作用...查看我的新帖子以获得更多解释。
【解决方案2】:

您可能只是遇到问题,因为您需要精确到分钟而不是秒?

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

【讨论】:

  • 对不起,它不起作用...查看我的新帖子以获得更多解释。
  • 我已经添加了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-05
  • 1970-01-01
相关资源
最近更新 更多