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

时间:2011-11-28 19:46:03

标签: java sql

使用pms-mlx,我一直在研究媒体库,以扩展ps3 media server的功能已有一段时间了,最​​近才发现了我的概念中的主要流程;如果使用多个一对多属性,则无法过滤。

在提问之前,我应该解释它是如何运作的 这是代码相关部分的DB结构。正在使用h2 DB schema video
每个视频都是一个文件,附加属性为0-n。

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

要检索所需文件,正在构建查询

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>

只有零件的位置和顺序是动态的。通过用相应的SQL副本替换条件名称(c1,c2)来创建where子句。对于上面的示例,将生成此where子句:

WHERE VIDEO.FILEID = FILE.ID 
  AND ((VIDEO.NAME LIKE 'A%' OR VIDEO.NAME LIKE 'B%') 
  AND FILE.DATEINSERTEDDB > '2011-09-28 18:48:43')

执行查询时,将为每个文件返回许多行。在遍历结果时,将添加raw中包含的“new”数据以创建对象。

当过滤器包含一对多条件时,查询分两步完成。首先,检索所有视频的ID,然后加载数据。

到目前为止,我一直缺少的是应该满足两个文件标签,两者都不再有效。 如果设置过滤器:
not working filter example
导致这个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条件?
我不是数据库专家,非常喜欢这个有好主意的人:)

生成where子句的代码位于DBFileInfo.java第445行的formatFilter方法中。如果有人有兴趣查看代码,则会在DBVideoFileInfo.java的第189行上加载数据。

2 个答案:

答案 0 :(得分:1)

您需要使用GUI来指定用户是否希望过滤器作为ANDOR使用。显然,在你的最后一种情况下,你需要OR。因此,您的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%')

请注意,消除了常见条件的重复,并将常用部分移出WHERE的上一级。

我认为你需要你的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%')

无论如何,这些只是 samples 查询的外观,具体取决于用户的输入。 原始问题,我是如何理解的,是关于特定情况,而不是一般解决方案。显然,在一般情况下,您的应用程序需要采用反映GUI中用户选择的不同条件。

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

答案 1 :(得分:1)

对于一个简单的问题示例,您的复杂表关系有点令人困惑,但是您是否只能建立一堆标准?

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])

肯定只返回有Brad,Angelina Elvis的文件? (可能不多)。