根据与条件匹配的整个子集选择行,

时间:2015-09-21 15:59:18

标签: sql subquery conditional-statements aggregate subset

我有一系列报告,我希望根据上传到系统的源信息显示为可供下载。每个报告可能存在多个报告期,可能需要在可用之前上传一个或多个源文件。

我的表格如下:

  • 报告 - 存储报告类型(ReportID)和描述
  • ReportDependency - 存储报告类型(ReportID)和 依赖关系生成该报告(可能是一个或多个)(SourceTypeID)
  • SourceType - 存储可能上传到系统的不同类型的源文件。
  • 来源 - 存储已上传的源数据文件(SourceTypeID,ReportingPeriodID和UploadDateTime)
  • 报告期间 - 存储各种报告期间。

TablesChart

根据可用的来源(上传到系统),我想显示可以生成/下载哪些报告。

我已经想出了这个,但这不正确:

SELECT
RD.ReportID, RP.ReportingPeriodID, COUNT(S.UploadDateTime) AS    
     DependenciesUploaded
FROM
ReportDependency RD
    INNER JOIN
Source S ON RD.SourceTypeID = S.SourceTypeID
    INNER JOIN
ReportingPeriod RP ON S.ReportingPeriodID = RP.ReportingPeriodID
GROUP BY
     RP.ReportingPeriodID, RD.ReportID
HAVING
    COUNT(S.UploadDateTime) = (SELECT COUNT(SourceTypeID) FROM ReportDependency WHERE ReportID = RD.ReportID)

如果我的数据如下:

enter image description here

我应该得到:

  • ReportsPeriod 1的报告1可用
  • 报告2尚不可用
  • ReportsPeriod 2的报告3可用

感谢您提供的任何帮助。

罗素

2 个答案:

答案 0 :(得分:0)

当你进行第一次内连接时,应该是

ReportDependency RD
  INNER JOIN
Source S ON RD.SourceTypeID = S.SourceTypeID

而不是

Source S ON RD.SourceTypeID = S.SourceID

这样您就不会将IDTYPEID进行比较。

答案 1 :(得分:0)

我继续努力...如果它对某人有帮助,这里的解决方案似乎有效(尚未完成测试)。 (我可能已经调整了一两张桌子,我无法记住;希望这足以帮助其他人。)

罗素

            SELECT
                *
            FROM
                (
                    SELECT DISTINCT
                        R.ReportID,
                        R.FilePathAndName,
                        RP.ReportingPeriodID,
                        COUNT(RD.SourceTypeID) OVER (PARTITION BY R.ReportID, R.FilePathAndName, RP.ReportingPeriodID) AS SourcesNeeded
                    FROM
                        luReportingPeriod RP
                            CROSS JOIN
                        Report R
                            INNER JOIN
                        ReportDependency RD ON R.ReportTypeID = RD.ReportTypeID
                            INNER JOIN
                        (
                        SELECT 
                        S.ReportingPeriodID,
                        S.SourceTypeID
                            FROM
                        luReportingPeriod RP
                            INNER JOIN
                        Source S ON (RP.ReportingPeriodID = S.ReportingPeriodID)
                            GROUP BY
                                S.ReportingPeriodID,
                                S.SourceTypeID
                        ) AS AvailableSources ON RP.ReportingPeriodID = AvailableSources.ReportingPeriodID AND RD.SourceTypeID = AvailableSources.SourceTypeID
                    GROUP BY
                        R.ReportID,
                        R.FilePathAndName,
                        RP.ReportingPeriodID,
                        RD.SourceTypeID
                ) AS Data
                INNER JOIN
                (
                    SELECT ReportTypeID, COUNT(SourceTypeID) AS SourcesNeeded
                    FROM
                        ReportDependency
                    GROUP BY ReportTypeID
                ) AS RequirementCount
                ON RequirementCount.ReportTypeID = Data.ReportID AND RequirementCount.SourcesNeeded = Data.SourcesNeeded
                INNER JOIN
                    luReportingPeriod ON Data.ReportingPeriodID = luReportingPeriod.ReportingPeriodID
                ORDER BY luReportingPeriod.Year DESC, luReportingPeriod.Month DESC, Data.FilePathAndName