使用缺失值连接SQL视图

时间:2013-01-28 18:45:42

标签: sql sql-server database sql-server-2005 views

我在两个不同的服务器上有两个视图。

这些视图输出名称,月份,计数

一个人(乔用户)可能只有7月,8月的一个视图,所以它会像这样显示

Joe User July 19
Joe User August 28

下一个观点可能会有更多

Joe User May 20
Joe User June 98
Joe User July 18
Joy User August 24

我想要显示的输出是这个。

Joe User January 0 0
Joe User February 0 0
Joe User March 0 0
Joe User April 0 0
Joe User May 20 0
Joe User June 98 0 
Joe User July 18 19
Joe User August 24 28
Joe User September 0 0
Joe User October 0 0
Joe User November 0 0
Joe User December 0 0

我的问题是即使他们没有价值观,我怎么能填上几个月?然后加入我拥有的值。

更新

通过以下示例,我得到了非常相似的结果。这是我在尝试运行它而不将名称添加到WHERE时获得的。

Joe User April 65 518
Joe User April 87 518
Joe User April 52 518
Joe User April 3  518

这会以每月64行的表值重复。

3 个答案:

答案 0 :(得分:3)

您需要使用日期表,然后使用JOIN两个表。否则,您可以在查询中创建一个,如下所示:

SELECT m.month, CASE WHEN c.ccount IS NULL THEN 0 ELSE c.ccount END AS view2,
CASE WHEN b.ccount IS NULL THEN 0 ELSE b.ccount END AS view1
FROM
(SELECT 'January' AS month
  UNION ALL
  SELECT 'February'
  UNION ALL
  SELECT 'March'
  UNION ALL
  SELECT 'April'
  UNION ALL
  SELECT 'May'
  UNION ALL
  SELECT 'June'
  UNION ALL
  SELECT 'July'
  UNION ALL
  SELECT 'August'
  UNION ALL
  SELECT 'September'
  UNION ALL
  SELECT 'November'
  UNION ALL
  SELECT 'December') m
LEFT JOIN (SELECT name, month, ccount FROM view1 WHERE name = 'Joe') b ON b.month = m.month
LEFT JOIN (SELECT name, month, ccount FROM view2 WHERE name = 'Joe') c ON c.month = m.month

<强>结果

|     MONTH | VIEW2 | VIEW1 |
-----------------------------
|   January |     0 |     0 |
|  February |     0 |     0 |
|     March |     0 |     0 |
|     April |     0 |     0 |
|       May |    20 |     0 |
|      June |    98 |     0 |
|      July |    18 |    19 |
|    August |    24 |    28 |
| September |     0 |     0 |
|  November |     0 |     0 |
|  December |     0 |     0 |

答案 1 :(得分:1)

首先,您必须创建链接服务器或使用OPENROWSET。 请使用OPENROWSET尝试此操作。

;WITH Months
AS
(
    SELECT 1 m, DATENAME(mm, '20000101') MN
    UNION ALL
    SELECT m+1, DATENAME(mm, DATEADD(m, m, '20000101')) MN
    FROM Months
    WHERE m < 12
)
SELECT
   COALESCE(V1.nmae, V2.name) Name, 
   M.MN [Month], 
   ISNULL(V1.count, 0) Count1, 
   ISNULL(V2.count, 0) Count12 
FROM Months M
    LEFT JOIN ViewOnCurrentServer V1
        ON M.MN = V1.[month]
    LEFT JOIN
         OPENROWSET('SQLNCLI', 'Server=YouServerName;Trusted_Connection=yes;',
                    'SELECT name, month, count
                     FROM DBName.SchemeName.ViewOnAnotherServer') V2
       ON M.MN = V2.[month]
WHERE COALESCE(V1.nmae, V2.name) = 'Joe User'

或者如果您使用链接服务器,请使用:

;WITH Months
AS
(
    SELECT 1 m, DATENAME(mm, '20000101') MN
    UNION ALL
    SELECT m+1, DATENAME(mm, DATEADD(m, m, '20000101')) MN
    FROM Months
    WHERE m < 12
)
SELECT
   COALESCE(V1.nmae, V2.name) Name, 
   M.MN [Month], 
   ISNULL(V1.count, 0) Count1, 
   ISNULL(V2.count, 0) Count12 
FROM Months M
    LEFT JOIN ViewOnCurrentServer V1
        ON M.MN = V1.[month]
    LEFT JOIN
         ViewOnLinkedServer V2
       ON M.MN = V2.[month]
WHERE COALESCE(V1.nmae, V2.name) = 'Joe User'

答案 2 :(得分:1)

SELECT DATENAME(mm, DATEADD(mm, number, '20010101')), 
       ISNULL(v2.[count], 0), ISNULL(v1.[count], 0)
FROM master..spt_values v LEFT JOIN view1 v1 ON DATENAME(mm, DATEADD(mm, v.number, '20010101')) = v1.[month] AND v1.name = 'Joe User'
                          LEFT JOIN view2 v2 ON DATENAME(mm, DATEADD(mm, v.number, '20010101')) = v2.[month] AND v2.name = 'Joe User'
WHERE v.type = 'P' AND v.number < 12

SQLFiddle上的演示

更新

SELECT *
FROM
(
 SELECT v1.name
 FROM view1 v1
 UNION
 SELECT v2.name
 FROM view2 v2
 ) u CROSS APPLY (
                  SELECT DATENAME(mm, DATEADD(mm, number, '20010101')) AS [month], 
                         ISNULL(v2.[count], 0) AS [count1], ISNULL(v1.[count], 0) AS [count2]                       
                  FROM master..spt_values v 
                    LEFT JOIN view1 v1 ON DATENAME(mm, DATEADD(mm, v.number, '20010101')) = v1.[month] AND v1.name = u.name
                    LEFT JOIN view2 v2 ON DATENAME(mm, DATEADD(mm, v.number, '20010101')) = v2.[month] AND v2.name = u.name
                  WHERE v.type = 'P' AND v.number < 12
                  ) o

SQLFiddle

上的新演示