2013-01-09 34 views
2

使用HSLQDB(2.2.9)我使用java JDBC连接的数据库。在不使用JOIN的情况下在HSQLDB中枢轴

某甲已接种疫苗的1和3,某乙已收到2和4 使用这个简单的查询:

SELECT std.*,vac.Date FROM Students AS std 
LEFT JOIN ValuesVaccination AS vac 
ON vac.ID_Students = std.ID 

我得到一个结果集,如:

ID | Name | ID_Vaccination | Date 
1 | PersonA | 1    | 2011-06-01 
1 | PersonA | 3    | 2012-03-21 
1 | PersonB | 2    | 2012-08-11 
2 | PersonB | 4    | 2012-09-08 

我想要得到的是:

ID | Name | Vaccination1 | Vaccination2 | Vaccination3 | Vaccination4 
1 | PersonA | 2011-06-01 | NULL  | 2012-03-21 | NULL 
2 | PersonB | NULL  | 2012-08-11 | NULL  | 2012-09-08 

一种方法是:

SELECT std.*, 
     vac1.Date AS "Vaccination1", 
     vac2.Date AS "Vaccination2", 
     vac3.Date AS "Vaccination3", 
     vac4.Date AS "Vaccination4" 
FROM Students AS std 
LEFT JOIN ValuesVaccination AS vac1 
ON vac1.ID_Students = std.ID AND vac1.ID_Vaccinations = 1 
LEFT JOIN ValuesVaccination AS vac2 
ON vac2.ID_Students = std.ID AND vac2.ID_Vaccinations = 2 
LEFT JOIN ValuesVaccination AS vac3 
ON vac3.ID_Students = std.ID AND vac3.ID_Vaccinations = 3 
LEFT JOIN ValuesVaccination AS vac4 
ON vac4.ID_Students = std.ID AND vac4.ID_Vaccinations = 4 

问题是数不同的疫苗接种是可变。有没有一种体面的方式来做到这一点,而不使用Java循环中的JOIN构建查询?

我想通了PIVOT函数是我所需要的,但似乎HSQLDB不支持它并搜索stackoverflow和谷歌没有提供有用的信息。

谢谢你的任何信息

回答

0

PIVOT是不是标准的SQL,它是一个扩展模块,仅通过Microsoft SQL Server 2005(后来)语法的支持,Oracle 11g

这是一个使用标准的SQL,应该在任何RDBMS工作的解决方案:

SELECT s.ID, s.Name, 
    MAX(CASE WHEN ID_Vaccination=1 THEN Date END) AS Vaccination1, 
    MAX(CASE WHEN ID_Vaccination=2 THEN Date END) AS Vaccination2, 
    MAX(CASE WHEN ID_Vaccination=3 THEN Date END) AS Vaccination3, 
    MAX(CASE WHEN ID_Vaccination=4 THEN Date END) AS Vaccination4 
FROM Students AS s 
LEFT JOIN ValuesVaccination AS v 
    ON s.ID = v.ID_Students 
GROUP BY s.ID, s.Name; 

回复您的评论:

SQL不允许的数据值在同一个动态生成新的列查询。因此, 任何数据透视查询要求您知道在准备查询之前,您希望在输出中显示多少个不同的疫苗接种。

您可以运行两个查询:一个“发现”设定不同的接种值:

SELECT DISTINCT ID_Vaccination FROM ValuesVaccination; 

然后取这回应用程序,并遍历它,添加列表达式,当您去,建立数据透视查询。

唯一的选择是获取所有加入到学生的数据,如在您的第一个查询中,并使用应用程序代码将其后处理为透视格式。

无论采用哪种方式,要生成动态数据透视查询,必须在准备查询之前或获取结果之前用应用程序代码对其进行补充。

+0

如果有10种不同的疫苗接种会怎么样?还是30?它们可以由应用程序用户创建和删除 – user1952162

+0

感谢您的回答,'MAX'函数正是我所需要的,因为可以有多个值,我需要显示最近的日期。 – user1952162

+0

'PIVOT'也受到Oracle的支持。 –

0

在比尔的回答中END)之后只有一个支架太多了。 要在这个线程使用别名和列名从原来的问题100%正确答案:

SELECT std.ID, std.Name, 
    MAX(CASE WHEN v.ID_Vaccinations=1 THEN Date END) AS Vaccination1, 
    MAX(CASE WHEN v.ID_Vaccinations=2 THEN Date END) AS Vaccination2, 
    MAX(CASE WHEN v.ID_Vaccinations=3 THEN Date END) AS Vaccination3, 
    MAX(CASE WHEN v.ID_Vaccinations=4 THEN Date END) AS Vaccination4 
FROM Students AS std 
LEFT JOIN ValuesVaccination AS v 
ON std.ID = v.ID_Students 
GROUP BY std.ID, std.Name 

返回所需的结果。

+0

谢谢,我编辑了我的答案来解决不平衡的parens。 –

相关问题