Java 媒体数据库中的一对多过滤

Java 媒体数据库中的一对多过滤,java,sql,Java,Sql,有了,我已经在一个媒体库上工作了一段时间来扩展的功能,最近在我的概念中发现了一个主要的流程;如果使用多个一对多属性,则无法进行筛选 在提问之前,我应该解释一下它是如何工作的。 下面是代码相关部分的DB结构。正在使用中。 每个视频都是一个文件,具有0-n个附加属性 一旦存储了一些视频,就可以通过设置条件在只显示所有条目子集的文件夹中查看和播放它们。下面是一个例子: 要检索想要的文件,查询的构造如下 SELECT <all_properties> FROM FILE, VIDEO

有了,我已经在一个媒体库上工作了一段时间来扩展的功能,最近在我的概念中发现了一个主要的流程;如果使用多个一对多属性,则无法进行筛选

在提问之前,我应该解释一下它是如何工作的。
下面是代码相关部分的DB结构。正在使用中。

每个视频都是一个文件,具有0-n个附加属性

一旦存储了一些视频,就可以通过设置条件在只显示所有条目子集的文件夹中查看和播放它们。下面是一个例子:

要检索想要的文件,查询的构造如下

SELECT <all_properties> 
FROM FILE, VIDEO
LEFT JOIN VIDEOAUDIO ON VIDEO.FILEID = VIDEOAUDIO.FILEID
LEFT JOIN SUBTITLES ON VIDEO.FILEID = SUBTITLES.FILEID
LEFT JOIN FILETAGS ON VIDEO.FILEID = FILETAGS.FILEID
LEFT JOIN FILEPLAYS ON VIDEO.FILEID = FILEPLAYS.FILEID
WHERE <whereClause>
ORDER BY <orderBy>
执行查询时,每个文件将返回许多行。在遍历结果时,将添加原始数据中包含的“新”数据以创建对象

当筛选器包含一对多条件时,将分两步执行查询。首先,检索所有视频的ID,然后加载数据

到目前为止,我一直缺少的是,如果有两个文件标签,并且两个标签都应该满足,那么任何东西都不起作用。 如果设置过滤器:

导致本where条款:

WHERE VIDEO.FILEID = FILE.ID 
  AND ((VIDEO.FILEID = FILETAGS.FILEID 
    AND FILETAGS.KEY = 'Actor' AND FILETAGS.VALUE LIKE 'A%') 
  AND (VIDEO.FILEID = FILETAGS.FILEID 
    AND FILETAGS.KEY = 'Actor' AND FILETAGS.VALUE LIKE 'B%'))
这是永远不会满足的,因为一行只包含一个键和一个值字段

是否可以创建一个查询,其中单个视频的所有数据都包含在一行中?或者用其他内容替换生成的SQL条件?
我不是db专家,我很想从有好主意的人那里学到:)


生成where子句的代码位于的第445行的formatFilter方法中。如果有人有兴趣查看代码,数据的加载将在第189行完成。

您需要GUI让用户指定他/她是否希望过滤器作为
工作。显然,在上一个例子中,您需要
。因此,您的
WHERE
子句如下所示:

WHERE VIDEO.FILEID = FILE.ID 
  AND VIDEO.FILEID = FILETAGS.FILEID
  AND FILETAGS.KEY = 'Actor'
  AND (FILETAGS.VALUE LIKE 'A%' OR FILETAGS.VALUE LIKE 'B%')
请注意,公共条件的重复被消除,公共部分被移出到
的上层,其中

我认为您需要GUI和SQL生成器来实现这一点


更新如果在结果影片中同时需要“A%”和“B%”,则需要将
WHERE
子句更改为

WHERE VIDEO.FILEID = FILE.ID
  AND EXISTS
  -- look if movie have 'A%' actor
  (SELECT 1 FROM FILETAGS WHERE 
  AND VIDEO.FILEID = FILETAGS.FILEID
  AND FILETAGS.KEY = 'Actor'
  AND FILETAGS.VALUE LIKE 'A%')
  AND EXISTS
  -- look if the same movie have 'B%' actor
  (SELECT 1 FROM FILETAGS WHERE 
  AND VIDEO.FILEID = FILETAGS.FILEID
  AND FILETAGS.KEY = 'Actor'
  AND FILETAGS.VALUE LIKE 'B%')
无论如何,这些只是查询的示例,取决于用户的输入。 最初的问题,我是如何理解它的,是关于特定的情况,而不是一个普遍的解决方案。显然,在一般情况下,您的应用程序将需要在GUI中采用反映用户选择的不同条件


对于一般情况,您需要某种形式的“SQLBuilder”,如。或者您可能想使用一些ORM工具,它将半自动地为您构建SQL。但是,如果您不太了解SQL,我建议您从SQL builder开始,以获得一些低级SQL体验。正确地使用ORM需要对SQL和相关内容有很好的理解。

对于一个简单的问题示例来说,您复杂的表关系有点让人困惑,但您是否可以不建立一系列标准

WHERE FILEID IN (SELECT [all files that have brad])
AND FILEID IN (SELECT [all files that have angelina])
AND FILEID IN (SELECT [all files that have elvis])

那肯定只会返回布拉德、安吉丽娜和埃尔维斯在里面的文件?(可能不多)。

谢谢,但不幸的是,这并没有涵盖我想要的所有案例。让我们举个例子;我们希望所有的电影都是布拉德·皮特和安吉丽娜·朱莉主演的,但这仍然不起作用。它不会在您给出的示例中选择任何内容。FILETAGS中没有同时具有“A%”和“B%”值的行,因此不会返回任何行。在当前实现中,第二个查询在结果集中始终有0行,对于单个结果行,只有一个键值对可用(其中值永远不会以A和B开头)。这就是为什么我问是否有可能在一行中获取所有视频属性。否则,algo必须对结果集中的多行进行过滤。我想知道一个制图员或制图员将如何完成这项工作;这一切是在SQL中完成的,还是有后处理?sqlbuilder可以完成这项工作;目前,我有自己的生成器来创建查询。为了澄清,我想介绍通过GUI创建过滤器的所有情况。目前,仅包含一对一条件的过滤器工作最佳;包含一对多条件的过滤器工作(通过执行两个DB查询);包含多个相同类型的一对多条件的过滤器不起作用。我目前可以想象这些解决方案。1) 查找具有嵌套select的子查询,该查询可用作“c1”。2) 将所有这一切移植到hibernate(AFAICT查询可以使用criterias完成)3)在加载数据后进行后处理(我希望避免这种情况,因为对于SQL查询和后处理,等式必须分为两个块;看起来相当棘手).这很可能是答案,但我不太确定如何从嵌套选择开始。我会尽我所能尝试的,谢谢。非常感谢!工作起来很有魅力。与其他查询相比有点慢,但它完全集成到现有的codeYes中,许多嵌套选择的性能可能是一场噩梦,特别是如果它们的索引很差的话。我使用的一个产品有一个审计表,它没有索引,数据以XML形式存在于单个varchar中,甚至没有PK。这些问题需要一段时间。。。
WHERE FILEID IN (SELECT [all files that have brad])
AND FILEID IN (SELECT [all files that have angelina])
AND FILEID IN (SELECT [all files that have elvis])