是否可以在Access 2003上使用CROSS JOIN + INNER和/或OUTER联接?如果是这样,怎么样?可能还需要子查询......?

时间:2012-08-15 18:26:26

标签: sql subquery ms-access-2003 cross-join

我有一个包含多个表格的数据库:[计划收入],[计划收入支出],[支持提供商],[Z服务代码新]

我已经编写了一个查询,它会计算出在lat 6 mos上特定服务代码中每个提供商列出的费用记录数量。唯一的问题是,理想情况下,我希望它也列出0的服务代码,其中在最后6个mos中记录了NO EXPENSES。

因此,基本上,我想与[支持提供商]表交叉[Z服务代码新]表,以获得提供商和所有服务代码之间的所有可能的匹配。然后,在每个服务代码中,我希望它计算最后6个mos中的费用记录数量(好吧,我实际上已经设置了自定义日期,因此它更灵活)。

但我不知道如何做到这一点,以便它不会将所有费用记录与所有服务代码相匹配,而只是将那些费用记录与正确的服务代码相匹配(如果有的话)。

[计划收入]。[服务]是与[Z服务代码新]匹配的外键。[服务代码] [计划收入]。[修订版ID]是一个与[计划收入费用]相匹配的外键。[RevID] [计划收入费用]。[SP]是与[支持提供商]匹配的外键。[ID]

不要问我为什么数据库构建器为了简单起见没有让他们的密钥从桌面到下一个匹配。它只是它的本质......

我当前的查询看起来像这样:


SELECT [support provider].[sp last],
       [support provider].[sp first],
       [support provider].[sp mi],
       [support provider].[agency],
       [support provider].[de?],
       [support provider].[ic?],
       [support provider].[agency?]     AS [AG?],
       [support provider].[generalbus?] AS [GB?],
       [ExpsToCount].[counted svc],
       Iif(Count([ExpsToCount].[exptocountid]) = 0, 0, Count(
       [ExpsToCount].[exptocountid]))   AS ExpCount
FROM   [support provider]
       LEFT JOIN (SELECT [plan revenue expense].[sp]          AS [Counted SP],
                         [z service codes new].[service code] AS [Counted Svc],
                         [plan revenue expense].[exp id]      AS [ExpToCountID]
                  FROM   [z service codes new]
                         LEFT JOIN ([plan revenue]
                                    LEFT JOIN [plan revenue expense]
                                           ON [plan revenue].[rev id] =
                                              [plan revenue expense].[revid])
                                ON [z service codes new].[service code] =
                                   [plan revenue].[service]
                  WHERE  ( [plan revenue expense].[checkdt] >=
                           Format([period beginning "mm/dd/yyyy"], "short date")
                           AND [plan revenue expense].[checkdt] <=
                 Format([periond ending "mm/dd/yyyy"], "short date") ))
                             AS ExpsToCount
              ON [ExpsToCount].[counted sp] = [support provider].[id]
WHERE  [support provider].[inactive?] = false
       AND ( [support provider].[de?] = true
              OR [support provider].[ic?] = true )
GROUP  BY [support provider].[sp last],
          [support provider].[sp first],
          [support provider].[sp mi],
          [support provider].[agency],
          [support provider].[de?],
          [support provider].[ic?],
          [support provider].[agency?],
          [support provider].[generalbus?],
          [ExpsToCount].[counted svc]
ORDER  BY [ExpsToCount].[counted svc],
          [support provider].[agency],
          [support provider].[sp last],
          [support provider].[sp first],
          [support provider].[sp mi],
          [ExpsToCount].[counted svc]; 

[IC?], [DE?], [Agency?], [GeneralBus?]只是表示支持提供程序类型的布尔字段。 同样,为什么数据库人选择了这个而不是一个带有外键的字段,所以你只能是一种类型的提供者,我不知道......只需滚动它。

所以,我现在也在使用子查询。

但是,它没有给我零服务代码没有费用。它只给了我一些ACTUAL费用,如果我不关心0的话会很好,我会这样做......如果只是为了我自己的启发。

我觉得在最后一天左右我已经和这件事情进行了对比。我的大脑是朋友。需要第二眼。

我觉得我需要与[Z服务代码新]交叉加入[支持服务提供商]以获得所有可能的匹配,然后以某种方式有选择地在没有相关费用记录的情况下给出0或者如果有则为COUNT有费用记录。但我想要为每个支持提供商提供单一服务代码,无论如何。

不确定将CROSS JOIN与Access中的某种INNER JOIN或OUTER JOIN组合的语法是什么?什么是最好的组合将是我的目的。我可以在没有子查询的情况下以某种方式离开,或者我是否仍然需要它?有没有比CROSS JOIN更好的方法呢? (我认为这就是CROSS JOIN的设计目的......但我可能错了?)

希望一切都有道理。思考?哦,我在Access 2003 Professional SP3上。


编辑:

好的,我自己优雅的解决方案(嗯,很好,我不知道它是否优雅,但它的工作原理!)是在我的主FROM行中创建两个自定义SELECT语句,然后基于JOIN加入两个SELECT语句两个匹配标准:


SELECT [ProvidersXCodes].[SP Last], [ProvidersXCodes].[SP First], [ProvidersXCodes].[SP MI], [ProvidersXCodes].[Agency], [ProvidersXCodes].[SvcCode], IIf(COUNT([ExpsToCount].[ExpCountID])=0,0,COUNT([ExpsToCount].[ExpCountID])) AS [Exp Count]

FROM (SELECT [Support Provider].[ID] AS [CodeProvider], [Support Provider].[SP Last], [Support Provider].[SP First], [Support Provider].[SP MI], [Support Provider].[Agency], [Z Service Codes New].[Service Code] AS [SvcCode]

FROM [Support Provider], [Z Service Codes New]

WHERE [Support Provider].[Inactive?]=FALSE
AND ([Support Provider].[DE?]=TRUE OR [Support Provider].[IC?]=TRUE)
AND NOT ([Z Service Codes New].[Service Code] LIKE '111*'
OR [Z Service Codes New].[Service Code] LIKE '222*'
OR [Z Service Codes New].[Service Code] LIKE '333*')

GROUP BY [Support Provider].[ID], [Support Provider].[SP Last], [Support Provider].[SP First], [Support Provider].[SP MI], [Support Provider].[Agency], [Z Service Codes New].[Service Code]) AS [ProvidersXCodes] 

LEFT JOIN (SELECT [Support Provider].[ID] AS [ExpCountProv], [Plan Revenue].[Service] AS [ExpCountSvc], [Plan Revenue Expense].[Exp ID] AS [ExpCountID]

FROM [Plan Revenue], [Plan Revenue Expense], [Support Provider]

WHERE [Plan Revenue].[Rev ID]=[Plan Revenue Expense].[RevID]
AND [Plan Revenue Expense].[SP]=[Support Provider].[ID]
AND [Support Provider].[Inactive?]=FALSE
AND ([Support Provider].[DE?]=TRUE OR [Support Provider].[IC?]=TRUE)
AND ([Plan Revenue Expense].[CheckDt]>=Format([Period Beginning "MM/DD/YYYY"],"Short Date") AND [Plan Revenue Expense].[CheckDt]<=Format([Periond Ending "MM/DD/YYYY"],"Short Date"))

GROUP BY [Support Provider].[ID], [Plan Revenue].[Service], [Plan Revenue Expense].[Exp ID]) AS [ExpsToCount] ON ([ProvidersXCodes].[CodeProvider]=[ExpsToCount].[ExpCountProv] AND [ProvidersXCodes].[SvcCode]=[ExpsToCount].[ExpCountSvc])

GROUP BY [ProvidersXCodes].[SP Last], [ProvidersXCodes].[SP First], [ProvidersXCodes].[SP MI], [ProvidersXCodes].[Agency], [ProvidersXCodes].[SvcCode]

ORDER BY [ProvidersXCodes].[SvcCode], [ProvidersXCodes].[Agency], [ProvidersXCodes].[SP Last], [ProvidersXCodes].[SP First], [ProvidersXCodes].[SP MI];

问题解决了!

我认为必须用语言表达问题才有助于解决问题,因为我自己考虑了实际问题是什么以及哪些特定信息需要成为跨产品而哪些信息需要更多标准连接操作以及如何正确链接这两组...

~MG(我)

1 个答案:

答案 0 :(得分:1)

好的,我自己看似优雅的解决方案(嗯,很好,我不知道它是否优雅,但似乎工作!)是在我的主要FROM子句中制作两个自定义SELECT语句,然后加入两个基于两个匹配条件的SELECT语句:


SELECT [ProvidersXCodes].[SP Last], [ProvidersXCodes].[SP First], [ProvidersXCodes].[SP MI], [ProvidersXCodes].[Agency], [ProvidersXCodes].[SvcCode], IIf(COUNT([ExpsToCount].[ExpCountID])=0,0,COUNT([ExpsToCount].[ExpCountID])) AS [Exp Count]

FROM (SELECT [Support Provider].[ID] AS [CodeProvider], [Support Provider].[SP Last], [Support Provider].[SP First], [Support Provider].[SP MI], [Support Provider].[Agency], [Z Service Codes New].[Service Code] AS [SvcCode]

FROM [Support Provider], [Z Service Codes New]

WHERE [Support Provider].[Inactive?]=FALSE
AND ([Support Provider].[DE?]=TRUE OR [Support Provider].[IC?]=TRUE)
AND NOT ([Z Service Codes New].[Service Code] LIKE '111*'
OR [Z Service Codes New].[Service Code] LIKE '222*'
OR [Z Service Codes New].[Service Code] LIKE '333*')

GROUP BY [Support Provider].[ID], [Support Provider].[SP Last], [Support Provider].[SP First], [Support Provider].[SP MI], [Support Provider].[Agency], [Z Service Codes New].[Service Code]) AS [ProvidersXCodes] 

LEFT JOIN (SELECT [Support Provider].[ID] AS [ExpCountProv], [Plan Revenue].[Service] AS [ExpCountSvc], [Plan Revenue Expense].[Exp ID] AS [ExpCountID]

FROM [Plan Revenue], [Plan Revenue Expense], [Support Provider]

WHERE [Plan Revenue].[Rev ID]=[Plan Revenue Expense].[RevID]
AND [Plan Revenue Expense].[SP]=[Support Provider].[ID]
AND [Support Provider].[Inactive?]=FALSE
AND ([Support Provider].[DE?]=TRUE OR [Support Provider].[IC?]=TRUE)
AND ([Plan Revenue Expense].[CheckDt]>=Format([Period Beginning "MM/DD/YYYY"],"Short Date") AND [Plan Revenue Expense].[CheckDt]<=Format([Periond Ending "MM/DD/YYYY"],"Short Date"))

GROUP BY [Support Provider].[ID], [Plan Revenue].[Service], [Plan Revenue Expense].[Exp ID]) AS [ExpsToCount] ON ([ProvidersXCodes].[CodeProvider]=[ExpsToCount].[ExpCountProv] AND [ProvidersXCodes].[SvcCode]=[ExpsToCount].[ExpCountSvc])

GROUP BY [ProvidersXCodes].[SP Last], [ProvidersXCodes].[SP First], [ProvidersXCodes].[SP MI], [ProvidersXCodes].[Agency], [ProvidersXCodes].[SvcCode]

ORDER BY [ProvidersXCodes].[SvcCode], [ProvidersXCodes].[Agency], [ProvidersXCodes].[SP Last], [ProvidersXCodes].[SP First], [ProvidersXCodes].[SP MI];

问题解决了!

我认为必须用语言表达问题才有助于解决问题,因为我自己考虑了实际问题是什么以及哪些特定信息需要成为跨产品而哪些信息需要更多标准连接操作以及如何正确链接这两组...

~MG(OP)