【问题标题】:select complement records in date range选择日期范围内的补充记录
【发布时间】:2014-10-04 08:21:34
【问题描述】:

我有以下两张表:

Table "Center":
CenterKey   CenterName
---------   -----------
Center1     CenterName1
Center2     CenterName2
Center3     CenterName3
Center4     CenterName4
Center5     CenterName5
Center6     CenterName6
Center7     CenterName7
Center8     CenterName8

Table "Log":
CenterKey   Date        Value
---------   --------    -----
Center1     6/1/2014    10
Center2     6/3/2014    20
Center1     7/2/2014    30
Center3     7/3/2014    40
Center4     7/5/2014    50
Center5     7/8/2014    60
Center6     8/3/2014    70

我有兴趣创建一个视图,比如“MyView”,如果我指定一个日期范围,它将返回其 CenterKey 不在该日期范围内的 CenterNames。

例如,如果我这样做

SELECT CenterName FROM MyView WHERE Date>='6/1/2014' AND Date <='6/30/2014'

我想要这个结果:

CenterName 
----------
CenterName3
CenterName4
CenterName5
CenterName6
CenterName7
CenterName8

如果我这样做

SELECT CenterName FROM MyView WHERE Date>='7/1/2014' AND Date <='7/31/2014'

我想要这个结果:

CenterName 
----------
CenterName2
CenterName6
CenterName7
CenterName8

如果我这样做

SELECT CenterName FROM MyView WHERE Date>='6/3/2014' AND Date <='7/5/2014'

我想要这个结果:

CenterName5
CenterName6
CenterName7
CenterName8

有人可以帮我创建 MyView 吗?

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    下面的查询应该做你想做的事:

    select c.centername
    from center c left outer join
         log l 
         on l.centerkey = c.centerkey
    group by c.centername
    having sum(l.Date >='2014-07-01' AND .Date <='2014-07-31') = 0;
    

    我想不出用where 子句轻松将其合并到视图中的方法。

    替代公式也没有真正的帮助:

    select c.centername
    from center c 
    where not exists (select 1
                      from log l
                      where l.centerkey = c.centerkey and
                            l.Date >= '2014-07-01' AND l.Date <='2014-07-31'
                     );
    

    编辑:

    如果你有日历表,你可以这样做:

    select c.centername, ca.dte
    from calendar ca cross join
         center c left outer join
         log l 
         on l.centerkey = c.centerkey and ca.dte = l.date
    where l.date is null;
    

    如果您将其放在带有where 的视图中,当中心可用时,您将获得该范围内每个日期的单独行。

    【讨论】:

    【解决方案2】:
    SELECT CenterName 
    FROM Center 
    WHERE CenterKey NOT IN 
    (     SELECT CenterKey 
          FROM Log 
          WHERE Date>='6/1/2014' AND Date <='6/30/2014' 
    )
    

    【讨论】:

    • 接近我想要的。我真的想创建一个可以根据我提供给视图的日期范围查询的视图。有什么办法可以做到这一点?我不想在日期中硬编码。
    • 我...不完全确定在这种情况下您想要什么。为您提供想要查看的内容的参数化查询看起来像这样(或者可能像给出的任何其他答案一样)。但是,创建后的视图只是一个表,如果您必须以任何一种方式进行选择,为什么不在原始表上进行呢?
    • 基本上我想创建一个视图,我可以使用 Crystal Reports 来获取在报告期间没有日志记录的中心列表。
    • 好的,但是...在两个表上执行连接查询以获取数据有什么问题?视图如何更好?它看起来完全没有必要,如果它存在,它需要包含来自 Center 和 Log 的所有数据才能独立工作....
    • 感谢您的帮助。我需要制作一个水晶报表,提示输入日期范围并列出该日期范围内没有日志记录的所有中心。由于日期范围是动态的,我真的需要一个视图。
    【解决方案3】:

    您只需加入表格:

    SELECT Centername FROM Center AS c NATURAL JOIN Log as L WHERE Date>='6/3/2014' AND Date <='7/5/2014'
    

    【讨论】:

      【解决方案4】:

      带参数查看

      最终 SQL 查询 (http://sqlfiddle.com/#!2/570cb8/1):

      SELECT *
      FROM
        (SELECT @startd:='2014-6-1', @endd:='2014-6-30') p , MyView;
      

      使用函数查看:

      create function startd() returns DATE DETERMINISTIC NO SQL return @startd;
      create function endd() returns DATE DETERMINISTIC NO SQL return @endd;
      
      create view MyView as
      select centername from center c where not exists
      (
        select 1 from log l where l.centerkey = c.centerkey AND
        d between startd() AND endd()
      );
      

      参考

      【讨论】:

        猜你喜欢
        • 2018-06-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-25
        • 1970-01-01
        相关资源
        最近更新 更多