【问题标题】:SQL Union All to display old data with new data?SQL Union All 用新数据显示旧数据?
【发布时间】:2009-06-15 15:56:18
【问题描述】:

在 MS Access 中,我有一些报告使用一些查询来显示某个日期范围内的数据。查询使用别名、if、sum 和 avg 函数,并连接多个表以获取其数据。

我想知道我是否可以使用 UNION ALL 以及包含所有必需字段的表来显示此表中的新数据以及旧数据,如果有人选择了跨越新的和旧的。

这是一个“旧”查询示例:

SELECT tblAssessment.fldValid, tblATraining.fldTID, tblATraining.fldTCrsID, 
tblCourses.fldCrsName, [fldCrsHrs]/8 AS Days, tblATraining.fldTLocAbr, 
tblDistrict.fldDistAbr, tblRegion.fldRegName, tblATraining.fldTDateStart, 
tblATraining.fldTDateEnd, tblATraining.fldTEnrolled, tblATraining.fldTPID, 
tblPersonnel.fldPName, tblAssessment.fldTrngSID, tblAssessment.Q1, 
IIf([fldValid]=True,IIf([Q1]>0,1,0),0) AS Q1Valid, tblAssessment.Q2, 
IIf([fldValid]=True,IIf([Q2]>0,1,0),0) AS Q2Valid, tblAssessment.Q3, 
IIf([fldValid]=True,IIf([Q3]>0,1,0),0) AS Q3Valid, tblAssessment.Q4, 
IIf([fldValid]=True,IIf([Q4]>0,1,0),0) AS Q4Valid, tblAssessment.Q5, 
IIf([fldValid]=True,IIf([Q5]>0,1,0),0) AS Q5Valid, tblAssessment.Q6, 
IIf([fldValid]=True,IIf([Q6]>0,1,0),0) AS Q6Valid, tblAssessment.Q7, 
IIf([fldValid]=True,IIf([Q7]>0,1,0),0) AS Q7Valid, tblAssessment.Q8, 
tblAssessment.Q9, 
IIf([fldValid]=True,IIf([Q9]>0,1,0),0) AS Q9Valid, tblAssessment.Q10, 
IIf([fldValid]=True,IIf([Q10]>0,1,0),0) AS Q10Valid, tblAssessment.Q11, 
IIf([fldValid]=True,IIf([Q11]>0,1,0),0) AS Q11Valid, tblAssessment.Q12, 
IIf([fldValid]=True,IIf([Q12]>0,1,0),0) AS Q12Valid, tblAssessment.Q13, 
tblAssessment.Q14, 
IIf([fldValid]=True,IIf([Q14]>0,1,0),0) AS Q14Valid, tblAssessment.Q15, 
IIf([fldValid]=True,IIf([Q15]>0,1,0),0) AS Q15Valid, tblAssessment.Q16, 
IIf([fldValid]=True,IIf([Q16]>0,1,0),0) AS Q16Valid, tblAssessment.Q17, 
IIf([fldValid]=True,IIf([Q17]>0,1,0),0) AS Q17Valid, tblAssessment.Q18, 
IIf([fldValid]=True,IIf([Q18]>0,1,0),0) AS Q18Valid, tblAssessment.Q19, 
IIf([fldValid]=True,IIf([Q19]>0,1,0),0) AS Q19Valid, tblAssessment.Q20, 
tblAssessment.Q21, 
IIf([fldValid]=True,IIf([Q21]>0,1,0),0) AS Q21Valid, tblAssessment.Q22, 
IIf([fldValid]=True,IIf([Q22]>0,1,0),0) AS Q22Valid, tblAssessment.Q23, 
IIf([fldValid]=True,IIf([Q23]>0,1,0),0) AS Q23Valid, tblAssessment.Q24, 
IIf([fldValid]=True,IIf([Q24]>0,1,0),0) AS Q24Valid, tblAssessment.Q25, 
IIf([fldValid]=True,IIf([Q25]>0,1,0),0) AS Q25Valid, tblAssessment.Q26, 
IIf([fldValid]=True,IIf([Q26]>0,1,0),0) AS Q26Valid, tblAssessment.Q27, 
IIf([fldValid]=True,IIf([Q27]>0,1,0),0) AS Q27Valid, tblAssessment.Q28, 
IIf([fldValid]=True,IIf([Q28]>0,1,0),0) AS Q28Valid, tblAssessment.Q29, 
tblAssessment.Q30, 
tblAssessment.Q31, tblAssessment.Q32
FROM ((tblDistrict 
       LEFT JOIN tblRegion ON tblDistrict.fldDRegID = tblRegion.fldRegID) 
       RIGHT JOIN (((tblATraining 
                     LEFT JOIN tblCourses ON tblATraining.fldTCrsID = tblCourses.fldCrsID) 
                   LEFT JOIN tblPersonnel ON tblATraining.fldTPID = tblPersonnel.fldPID) 
                  LEFT JOIN tblLocations ON tblATraining.fldTLocAbr = tblLocations.fldLID) ON tblDistrict.fldDistAbr = tblATraining.fldTDistAbr) 
     LEFT JOIN tblAssessment ON tblATraining.fldTID = tblAssessment.fldTrngCID
WHERE (((tblAssessment.fldValid)=True) 
        AND ((tblATraining.fldTCrsID) Like [forms]![fdlgRptCriteria].[selCrsCd]) 
        AND ((tblATraining.fldTDateStart) Between [forms]![fdlgRptCriteria].[seldate1] And [forms]![fdlgRptCriteria].[seldate2]) 
        AND ((tblAssessment.fldTrngSID) Is Not Null));

【问题讨论】:

  • 尝试使用代码块 - 它会保留您的格式。
  • 我尽力把它格式化成一些可读的东西。我对连接顺序的明确性感到困惑(Access 是否会遵守您指定的确切方式还有待商榷),以及 WHERE 子句中的所有括号,但这没关系。
  • @lc: ACE/Jet 强制通过要求每个连接(最后一个连接除外)放在括号中来明确连接顺序。但是您是正确的,因为优化器可以在认为合适的情况下更改顺序,所以不能保证 JOIN 顺序(这是 ACE/Jet 不符合标准 SQL 的另一种方式)。
  • 感谢大家对这个非常古老的问题的所有意见!对不起,我 7 年前没有说谢谢!

标签: sql ms-access union


【解决方案1】:

是的,但您可以考虑为联合创建一个新的 querydef。

(您需要使用我上次检查时的 SQL 设计窗口。)

大概是:

    SELECT
    tblATraining.fldTID,
    tblATraining.fldTCrsID,
    tblATraining.fldTLocAbr,
    tblATraining.fldTDateStart,
    tblATraining.fldTDateStart,
    tblATraining.fldTDateEnd,
    tblATraining.fldTEnrolled,
    tblATraining.fldTPID

    UNION ALL

    tblATrainingArchive.fldTID,
    tblATrainingArchive.fldTCrsID,
    tblATrainingArchive.fldTLocAbr,
    tblATrainingArchive.fldTDateStart,
    tblATrainingArchive.fldTDateStart,
    tblATrainingArchive.fldTDateEnd,
    tblATrainingArchive.fldTEnrolled,
    tblATrainingArchive.fldTPID

并将其命名为 tblATrainingUnion。

然后只要将它插入到您现有的查询中,无论您有 tblATraining。

注意:许多人还倾向于在真正有意义之前创建存档表 - 您可能会考虑将其全部保留在主表中,并在您可以实际衡量差异时进行拆分。 (您可能已经达到了这一点并做到了这一点;使用 Access 比使用 SQL Server 更有意义。)

【讨论】:

  • 是的,我会尝试对其进行设置,以便将联合的使用限制为按需使用。大记录集的联合是出了名的缓慢。
  • “你可能会考虑为联合创建一个新的 querydef...你需要使用我上次检查时的 SQL 设计窗口”——实际上,上次检查时 querydef 是一个 DAO 对象,因此您需要使用 DAO :) FWIW DAO 的 querydef 映射到 ACE/Jet 的 VIEW 或 PROCEDURE,即 DAO 会丢失两者之间的粒度。
  • @le dorfier:你不需要使用表名来限定列,因为范围内只有一个表......好吧,当你实际添加行'FROM tblATraining ' :) 同上 tblATrainingArchive。
  • Querydefs 不是 API 的产物;它们是(或至少曾经是)访问中存储的查询。他们需要一个新词——它既不是视图也不是存储过程。
  • 我想知道是否可以合并所有查询,即使它具有 WHERE 条件,接受表单中的日期范围
【解决方案2】:

是的,Access 支持UNION ALL。一个简单的例子是:

select foo from OldData
union all
select foo from NewData

【讨论】:

    【解决方案3】:

    我会强调@le dorfier 关于归档的评论。大多数具有 Jet 数据存储的 Access 应用程序不需要存档数据。我的一个客户运行一个计费系统,用于我在 1997-98 年为她建造的 6 个停车场(从那时起,它已经进行了广泛的升级、扩展和修改)。它包括整个期间的数据(每个车库每个月有 200-300 张发票),它现在的运行速度和当时一样快。部分原因是 PC 性能的提高(即,在数据量相同的情况下,使用 1997 年的 PC,它可能会很慢),但它仍然可以正常工作。

    如果速度开始成为问题,我们可能会将后端移至 SQL Server Express。我们考虑的最后一件事是归档数据。

    我的另一个客户坚持归档他们的非活动数据,然后我不得不重新编程添加新记录功能以检查存档(由于应用程序的要求,同一个人没有新记录至关重要已创建,而是从存档中检索)。这大大减慢了添加新记录的过程。现在我正试图说服他们“取消归档”他们的数据,因为这实际上并没有以任何方式帮助他们,而且在日常运营中让事情变得更慢。

    【讨论】:

      【解决方案4】:

      与您的问题无关的两个 cmets。

      1) Q1 到 Q32 字段的用途是什么?我在想也许这些可以以某种方式重新设计和/或规范化。

      2) 我认为没有理由对对象名称使用命名标准。如tbl、fld、frm、qry等。您几乎可以通过代码中的上下文知道它们是什么类型的对象。如果在各种数据库容器窗口中,这些也很明显。

      也就是说,我确实在我的 VBA 代码中使用了变量命名约定,只是为了帮助保持清晰。

      请参阅Tony's Object Naming Conventions 和Tony's Table and Field Naming Conventions 了解更多详情。

      我非常希望有些人强烈反对我的第二条评论并拒绝我的帖子。

      【讨论】:

      • 关于 tbl、fld、frm、qry,除了 tbl 和 qry 之外,我可以在没有它们的情况下相处,这是因为 Access 将 tabledefs 和 querydefs 呈现为单个命名空间,我需要能够区分两者。也就是说,在对我没有创建的现有应用程序进行大修期间,我经常会创建一个名为 tblMyTable 的查询,它是真正的 MyTable 的替代品。这是一个查询,但它的命名就像是一个表,但这完全是暂时的,因为我正在重新设计 UI 并且无法重组后端以符合新标准。
      猜你喜欢
      • 1970-01-01
      • 2019-05-28
      • 2011-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多