mysql - MySQL 交叉表查询中缺少列

标签 mysql crosstab dynamicquery

因此,我为我的客户提供了一个非常复杂的交叉表查询,该客户负责管理各个大学的学生援助。 查询是动态的,因此它在存储过程中构建为长字符串,然后准备、执行和释放。

我已经能够提取最终的查询,该查询大约有 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

使用上述代码使查询成为联合查询是可行的。返回所有列,但顶部有一个“空”行,我必须为其编码。

请记住,查询非常复杂,必须使用大量 concat 来构建,而且我必须执行 group_concat 只是为了获取可能的联邦程序的名称。这为我创建了 case 语句,这些语句被注入(inject)到主 SQL 语句中。

那么除了执行联合查询之外,还有什么方法可以强制所有列出现? 希望我把问题说清楚了。

谢谢...

编辑: 事实证明添加联合查询根本不起作用。我正在运行的数据已经包括所有联邦项目的记录。如果我使用不包含某些联邦程序的数据集运行联合查询,则会收到有关 2 个查询与列计数不匹配的错误。因此,我仍然遇到返回交叉表部分中所有可能的列的问题。

最佳答案

无法解决这个问题,所以我用不同的方式解决了这个问题。由于交叉表查询不会提供交叉表中任何在基础数据中不是有效值的列,因此我创建了一个包含所有可能列的表,然后从交叉表查询中截断并填充该表。最后,从该表中进行选择。现在显示所有可能的列。

关于mysql - MySQL 交叉表查询中缺少列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58985927/

相关文章:

entity-framework - 向所有请求 EF6 添加 Where 条件

mysql - 使用 python 2.7 和 MySQLdb 的动态 LIKE 查询

mysql - MySQL 中的大型唯一键

python - 如何根据条件从数据框中交叉制表列?

php - 根据类型计算一个月中每一天的行之间的差异

sorting - 如何在 jasper 中对交叉表的列标题值进行排序?

java - 如何使用Java代码强制交叉表忽略宽度?

c# - EF中的主键最大值

mysql - 如何从 [MySQL] Plesk 数据库获取所有域的过期日期?

执行 ALTER 时 MySQL InnoDB 行/表锁