我有2个数据库表
JOBS(JOB_ID, JOB_TIME, JOB_NAME,...), JOB_PARAMETERS(JOB_ID,NAME,VALUE)
其中JOB_PARAMETERS本质上是一个包含作业参数键值对的映射。 每个作业可能具有唯一的参数键/值对。
我希望以实用的方式构建一个查询,该查询将返回包含键/值组合的不同作业ID。其中值实际上是值列表,比较运算符。 例如:
JOB_PARAMETERS: NAME = 'OUTPUT_FILENAME', VALUE LIKE "ALEX%", "JAX%"
NAME = 'PRIORITY' , VALUE > 7
上面的示例将自动过滤掉所有没有OUTPUT_FILENAME和PRIORITY键的作业。返回满足这两个条件的所有工作。
我还需要能够支持分页和排序。
我计划将Perl与DBIx :: Class一起使用,但我也可以在纯Perl / SQL中使用它。
我愿意更改数据库架构,但每个作业都可以有不同的键/值对,所以我不能在作业表中创建它们。
提前致谢。
答案 0 :(得分:1)
可以在SQL中执行此操作,方法是将JOB_PARAMETERS
分组为JOB_ID
并相应地过滤组。例如,如果(JOB_ID, NAME)
上存在唯一性约束,则可以按如下方式进行查询:
SELECT JOB_ID
FROM JOB_PARAMETERS
WHERE (NAME='OUTPUT_FILENAME' AND (VALUE LIKE 'ALEX%' OR VALUE LIKE 'JAX%'))
OR (NAME='PRIORITY' AND VALUE > 7)
GROUP BY JOB_ID
HAVING COUNT(*) = 2
如果没有这样的唯一性约束,则必须替换COUNT(*)
,例如与COUNT(DISTINCT NAME)
。
答案 1 :(得分:1)
使用DBIx :: Class时,可以使用Schema :: Loader生成DBIC模式。
连接到数据库后,您将获得一个$ schema对象,您可以使用它来过滤ResultSet以返回所需的Result对象:
my $rs_job_parameters = $schema->resultset('Job_Parameters')->search({
-or => [
{
'name' => 'OUTPUT_FILENAME',
'value' => [{ like => 'ALEX%'}, { like => 'JAX%' }].
},
{
'name' => 'PRIORITY',
'value' => [{ '>' => 7}].
}
]},
{
columns => [qw( job_id )],
group_by => [qw( job_id )], # alternative you can use distinct => 1 to group_by all selected columns
having => \[ 'COUNT(*) = ?', [ 2 ] ],
}
);
my @job_ids = $rs_job_parameters->get_column('job_id')->all;