MySQL 交叉表查询中缺少列
Missing Column(s) in MySQL Crosstab Query
所以我的客户有一个非常复杂的交叉表查询,他管理着各个学院的学生资助。
查询是动态的,因此它在存储过程中构建为一个长字符串,然后准备、执行和释放。
我已经能够提取出最终查询,它大约有 2000 个字符长。
select concat(s.LastName, ', ', s.FirstName, ' ', ifnull(s.MiddleInit, '')) as StudentName, p.SSN,
case @fullSSN when 0 then concat('xxxx-xx-', right(p.ssn, 4)) else concat(left(p.ssn, 3), '-',
substr(p.ssn, 4, 2), '-', right(p.ssn, 4)) end as formattedSSN,
sp.AwardYear, c.CampusName, es.EnrollmentStatus, sp.LoanPeriodFrom, sp.LoanPeriodTo, pg.ProgramName,
concat(s.Address1, ', ', s.City, ', ', s.State, ' ', s.Zip) as Address, s.Email, s.DOB,
sp.StartDate, sp.EndDate as LDA, sp.VerifyType,
sum(case when FedPgmName = 'DL Subsidized' then Amount end) as 'DL Subsidized',
sum(case when FedPgmName = 'DL Unsubsidized' then Amount end) as 'DL Unsubsidized',
sum(case when FedPgmName = 'Pell' then Amount end) as 'Pell',
sum(case when FedPgmName = 'DL PLUS' then Amount end) as 'DL PLUS',
sum(case when FedPgmName = 'FSEOG' then Amount end) as 'FSEOG',
sum(case when FedPgmName = 'FWS' then Amount end) as 'FWS'
from Payments as p inner join Student as s on p.SchoolID = s.SchoolID and p.SSN = s.SSN inner join
(select SchoolID, SSN, Max(StudentProfileID) as MaxProfileID from StudentProfile group by SchoolID,
SSN) as max on p.SchoolID = max.SchoolID and p.ssn = max.ssn inner join StudentProfile as sp on
max.SchoolID = sp.SchoolID and max.SSN = sp.SSN and max.MaxProfileID = sp.StudentProfileID inner
join Program as pg on sp.SchoolID = pg.SchoolID and sp.ProgramID = pg.ProgramID inner join as fp
on p.FedPgmID = fp.FedPgmID inner join Campuses as c on sp.SchoolID = c.SchoolID and sp.CampusID =
c.CampusID inner join EnrollmentStatus as es on sp.EnrollmentStatusID = es.EnrollmentStatusID where
p.SchoolID = 'cbd' and CkDate between '2018-01-01' and '2018-12-31' and sp.ProgramID in(161, 24, 25,
168, 165, 166, 14, 159, 160, 13, 150, 151, 17, 23, 10, 15, 2, 16, 3, 26, 9, 21, 22, 1, 11, 12, 19,
20, 4, 18, 8, 5, 6, 7) and p.FedPgmID in(1, 8, 9, 10, 5, 6, 23) and sp.EnrollmentStatusID in(1, 10,
2, 3, 4, 5, 6, 7, 8, 9) and ifnull(CkNo, 0) > 0 group by StudentName, SSN, formattedSSN, AwardYear,
CampusName, EnrollmentStatus, LoanPeriodFrom, LoanPeriodTo, ProgramName
确切地知道这里发生了什么并不重要,除了我的问题涉及上面的交叉表代码,其中有几个不同联邦程序名称的情况。如果底层数据包含提到的所有不同程序,那么一切正常。如果数据中缺少任何提到的情况(例如没有包含 "FWS" 的行),则该列不会显示在结果中,并且我的代码有问题,因为它期望返回所有列。
所以我想弄清楚如何确保返回所有列。如果我将以下内容添加到生成的 SQL 代码的开头,它就可以正常工作:
select '' as StudentName, '' as SSN, '' as formattedSSN, '' as AwardYear, '' as CampusName, '' as EnrollmentStatus,
'' as LoanPeriodFrom,
'' as LoanPeriodTo, '' as ProgramName, '' as Address, '' as Email, '' as DOB, '' as StartDate, '' as LDA, '' as VerifyType,
select 0 as 'DL Subsidized', 0 as 'DL Unsubsidized', 0 as 'Pell', 0 as 'DL PLUS', 0 as 'FSEOG', 0 as 'FWS'
union
使用上述代码使查询成为联合查询有效。所有列都被返回,但是我在顶部有一个 "empty" 行,我必须为其编码。
请记住查询非常复杂,必须使用大量连接来构建,而且我必须执行 group_concat 只是为了获取可能的联邦计划的名称。这为我创建了 case 语句,这些语句被注入到主 SQL 语句中。
那么除了执行联合查询之外,还有什么方法可以强制显示所有列吗?
希望我把问题说清楚了。
谢谢...
编辑:
事实证明添加联合查询毕竟不起作用。我正在 运行 删除已经包含所有联邦计划记录的数据。如果我 运行 使用不包含某些联邦程序的数据集进行联合查询,我会收到有关 2 个查询与列数不匹配的错误。所以我仍然无法返回交叉表部分中所有可能的列。
想不通,所以我用不同的方法解决了这个问题。由于交叉表查询不会在交叉表中提供任何不是基础数据中有效值的列,因此我创建了一个 table 包含所有可能的列,然后截断并填充交叉表中的 table询问。最后,select来自那个table。现在显示所有可能的列。
所以我的客户有一个非常复杂的交叉表查询,他管理着各个学院的学生资助。 查询是动态的,因此它在存储过程中构建为一个长字符串,然后准备、执行和释放。
我已经能够提取出最终查询,它大约有 2000 个字符长。
select concat(s.LastName, ', ', s.FirstName, ' ', ifnull(s.MiddleInit, '')) as StudentName, p.SSN,
case @fullSSN when 0 then concat('xxxx-xx-', right(p.ssn, 4)) else concat(left(p.ssn, 3), '-',
substr(p.ssn, 4, 2), '-', right(p.ssn, 4)) end as formattedSSN,
sp.AwardYear, c.CampusName, es.EnrollmentStatus, sp.LoanPeriodFrom, sp.LoanPeriodTo, pg.ProgramName,
concat(s.Address1, ', ', s.City, ', ', s.State, ' ', s.Zip) as Address, s.Email, s.DOB,
sp.StartDate, sp.EndDate as LDA, sp.VerifyType,
sum(case when FedPgmName = 'DL Subsidized' then Amount end) as 'DL Subsidized',
sum(case when FedPgmName = 'DL Unsubsidized' then Amount end) as 'DL Unsubsidized',
sum(case when FedPgmName = 'Pell' then Amount end) as 'Pell',
sum(case when FedPgmName = 'DL PLUS' then Amount end) as 'DL PLUS',
sum(case when FedPgmName = 'FSEOG' then Amount end) as 'FSEOG',
sum(case when FedPgmName = 'FWS' then Amount end) as 'FWS'
from Payments as p inner join Student as s on p.SchoolID = s.SchoolID and p.SSN = s.SSN inner join
(select SchoolID, SSN, Max(StudentProfileID) as MaxProfileID from StudentProfile group by SchoolID,
SSN) as max on p.SchoolID = max.SchoolID and p.ssn = max.ssn inner join StudentProfile as sp on
max.SchoolID = sp.SchoolID and max.SSN = sp.SSN and max.MaxProfileID = sp.StudentProfileID inner
join Program as pg on sp.SchoolID = pg.SchoolID and sp.ProgramID = pg.ProgramID inner join as fp
on p.FedPgmID = fp.FedPgmID inner join Campuses as c on sp.SchoolID = c.SchoolID and sp.CampusID =
c.CampusID inner join EnrollmentStatus as es on sp.EnrollmentStatusID = es.EnrollmentStatusID where
p.SchoolID = 'cbd' and CkDate between '2018-01-01' and '2018-12-31' and sp.ProgramID in(161, 24, 25,
168, 165, 166, 14, 159, 160, 13, 150, 151, 17, 23, 10, 15, 2, 16, 3, 26, 9, 21, 22, 1, 11, 12, 19,
20, 4, 18, 8, 5, 6, 7) and p.FedPgmID in(1, 8, 9, 10, 5, 6, 23) and sp.EnrollmentStatusID in(1, 10,
2, 3, 4, 5, 6, 7, 8, 9) and ifnull(CkNo, 0) > 0 group by StudentName, SSN, formattedSSN, AwardYear,
CampusName, EnrollmentStatus, LoanPeriodFrom, LoanPeriodTo, ProgramName
确切地知道这里发生了什么并不重要,除了我的问题涉及上面的交叉表代码,其中有几个不同联邦程序名称的情况。如果底层数据包含提到的所有不同程序,那么一切正常。如果数据中缺少任何提到的情况(例如没有包含 "FWS" 的行),则该列不会显示在结果中,并且我的代码有问题,因为它期望返回所有列。
所以我想弄清楚如何确保返回所有列。如果我将以下内容添加到生成的 SQL 代码的开头,它就可以正常工作:
select '' as StudentName, '' as SSN, '' as formattedSSN, '' as AwardYear, '' as CampusName, '' as EnrollmentStatus,
'' as LoanPeriodFrom,
'' as LoanPeriodTo, '' as ProgramName, '' as Address, '' as Email, '' as DOB, '' as StartDate, '' as LDA, '' as VerifyType,
select 0 as 'DL Subsidized', 0 as 'DL Unsubsidized', 0 as 'Pell', 0 as 'DL PLUS', 0 as 'FSEOG', 0 as 'FWS'
union
使用上述代码使查询成为联合查询有效。所有列都被返回,但是我在顶部有一个 "empty" 行,我必须为其编码。
请记住查询非常复杂,必须使用大量连接来构建,而且我必须执行 group_concat 只是为了获取可能的联邦计划的名称。这为我创建了 case 语句,这些语句被注入到主 SQL 语句中。
那么除了执行联合查询之外,还有什么方法可以强制显示所有列吗? 希望我把问题说清楚了。
谢谢...
编辑: 事实证明添加联合查询毕竟不起作用。我正在 运行 删除已经包含所有联邦计划记录的数据。如果我 运行 使用不包含某些联邦程序的数据集进行联合查询,我会收到有关 2 个查询与列数不匹配的错误。所以我仍然无法返回交叉表部分中所有可能的列。
想不通,所以我用不同的方法解决了这个问题。由于交叉表查询不会在交叉表中提供任何不是基础数据中有效值的列,因此我创建了一个 table 包含所有可能的列,然后截断并填充交叉表中的 table询问。最后,select来自那个table。现在显示所有可能的列。