2

我为 Microsoft SQL Server 2008 R2 编写了以下查询...

with 
downloads as
(
    select convert(varchar(10), timestamp, 112) as downloadDate, COUNT(*) as counter 
    from <download_table> 
    group by convert(varchar(10), timestamp,112)
),
uploads as 
(
    select CONVERT(varchar(10), dateadded, 112) as uploadDate, COUNT(*) as counter
    from <upload_table>
    group by CONVERT(varchar(10), dateadded, 112)
)
select 
    downloads.downloadDate, 
    uploads.uploadDate, 
    downloads.counter as dCount,
    uploads.counter as uCount
from downloads 
full join uploads on uploads.uploadDate = downloads.downloadDate
order by downloadDate desc;

它返回下表...

downloadDate    uploadDate  dCount  uCount
20121211    NULL        40  NULL
20121210    NULL        238 NULL
20121207    20121207    526 4
20121206    20121206    217 12
20121205    NULL        108 NULL
20121204    20121204    190 13
20121203    NULL        141 NULL
20121130    20121130    248 187
20121129    NULL        134 NULL
20121128    NULL        102 NULL
20121127    20121127    494 57
20121126    NULL        153 NULL
20121119    20121119    319 20
20121118    NULL        4   NULL
20121116    20121116    215 16
20121112    20121112    431 144
20121109    20121109    168 48
20121108    20121108    132 181
NULL        20121125    NULL    3

但是如果没有一些 NULL 条目,我无法将两个日期组合成一个“日期”列,也无法让 dCount 或 uCount 中的 NULL 值显示 0 而不是 NULL。

有人可以帮我吗?

4

4 回答 4

2

根据您的 SQL 方言,类似IFNULL(), NVL(),COALESCE()IIF()的内容将帮助您摆脱 NULL 以支持过去的日期,例如 '18000101'。

完成后,您可以使用MAX()SWITCH()IIF()IF()朋友创建一个“最后使用日期”列。

于 2012-12-11T11:34:37.307 回答
2

在 SQL Serve,r 中,您可以COALESCE在返回第一个非空值的日期字段ISNULL周围和在总数周围使用以将null值替换为零:

with 
downloads as
(
    select convert(varchar(10), timestamp, 112) as downloadDate, COUNT(*) as counter 
    from download_table 
    group by convert(varchar(10), timestamp,112)
),
uploads as 
(
    select CONVERT(varchar(10), dateadded, 112) as uploadDate, COUNT(*) as counter
    from upload_table
    group by CONVERT(varchar(10), dateadded, 112)
)
select 
    coalesce(downloads.downloadDate, uploads.uploadDate) as dDate, 
    isnull(downloads.counter, 0) as dCount,
    isnull(uploads.counter, 0) as uCount
from downloads 
full join uploads 
  on uploads.uploadDate = downloads.downloadDate
order by downloadDate desc;

请参阅带有演示的 SQL Fiddle

结果:

|    DDATE | DCOUNT | UCOUNT |
------------------------------
| 20121211 |      2 |      0 |
| 20121210 |      1 |      1 |
| 20121207 |      1 |      0 |
| 20121206 |      2 |      1 |
| 20121208 |      0 |      1 |
| 20121209 |      0 |      1 |
| 20121204 |      0 |      1 |
| 20121205 |      0 |      1 |
于 2012-12-11T11:38:16.123 回答
1

您可以像这样使用 coalesce 和 nvl:

with 
downloads as
(
    select convert(varchar(10), timestamp, 112) as downloadDate, COUNT(*) as counter 
    from <download_table> 
    group by convert(varchar(10), timestamp,112)
),
uploads as 
(
    select CONVERT(varchar(10), dateadded, 112) as uploadDate, COUNT(*) as counter
    from <upload_table>
    group by CONVERT(varchar(10), dateadded, 112)
)
select 
    coalesce(downloads.downloadDate, uploads.uploadDate) as dDate, 
    nvl(downloads.counter, 0) as dCount,
    nvl(uploads.counter, 0) as uCount
from downloads 
full join uploads on uploads.uploadDate = downloads.downloadDate
order by downloadDate desc;
于 2012-12-11T11:35:09.947 回答
1

首先,如果要删除时间元素,最好将日期时间转换为日期,而不是转换为 varchar,在 SQL-Server 2008 中,您可以简单地使用:

CAST(DateAdded AS DATE)

然后,我不会使用 FULL JOIN 来执行此操作UNION ALL,它应该会执行得更好(尽管如果不测试您的实际数据,我不能说 100%)。

WITH Data AS
(   SELECT  [Date] = CAST(Timestamp AS DATE),
            [Downloads] = 1,
            [Uploads] = 0
    FROM    Download_Table
    UNION ALL
    SELECT  [Date] = CAST(DateAdded AS DATE),
            [Downloads] = 0,
            [Uploads] = 1
    FROM    Upload_Table
)
SELECT  [Date], 
        [Downloads] = SUM(Downloads),
        [Uploads] = SUM(Uploads)
FROM    Data
GROUP BY [Date]
ORDER BY [Date];
于 2012-12-11T11:41:33.500 回答