我有两个表DOCUMENT和ATTRIBUTES就像这些
DOCUMENT(id)
,ATTRIBUTE(name, value, doc_fk)
。我需要运行一个类似这样的查询"抽象查询"
select top 100 documents
where $state='COMPLETED'
order by $creationDate
$state
和$creationDate
是两个属性。
请注意,限制是在文档上,而不是属性上,排序和过滤器在两个不同的属性上。最终查询应该返回所有文档属性,而不仅仅是过滤/排序的属性。
我能用非常复杂的查询来写这个,我正在寻找更好的选择。如果有用,我可以发布我的解决方案,但我不想指出你可能是错误的方向。
可以获得一些额外的文件,比如1000而不是100,并在内存中过滤/排序。 可以确定限制不准确,例如74而不是所需的限制100,但距离它不太远。
额外"软"要求:
预期的输出是这样的
DOC_ID ATTRIBUTE_NAME VALUE
123 state COMPLETED
123 creationDate 21/11/2012
123 userid someone
456 state COMPLETED
...
答案 0 :(得分:0)
啊,EAV设计的缺陷。
试试这个。
select
top 100
document.*
from document
inner join attribute astate on document.id = astate.doc_fk
and astate.name='state'
and astate.value = 'completed'
inner join attribute acreation on document.id = acreation.doc_fk
and acreation.name='creationdate'
order by cast(acreation.value as date)
但如果坚持使用这种EAV结构,它只会变得更加复杂。
(PS.MySQL不使用TOP,而是使用LIMIT)
答案 1 :(得分:0)
SELECT doc_id, attr_name, attr_val, creationDate FROM
(
SELECT * FROM (
SELECT
doc.id as 'doc_id', attr.name as 'attr_name', null as 'attr_val', attr.value as 'creationDate'
FROM
ATTRIBUTE attr
LEFT JOIN
DOCUMENT doc ON attr.doc_fk = doc.id
WHERE
attr.name='creationDate'
ORDER BY creationDate desc;
) AS dt1
UNION ALL
SELECT * FROM(
SELECT
doc.id as 'doc_id', attr.name as 'attr_name', attr.value as 'attr_val', null as 'creationDate'
FROM
ATTRIBUTE attr
LEFT JOIN
DOCUMENT doc ON attr.doc_fk = doc.id;
) as dt2
) as dt0 GROUP BY doc_id ORDER by creationDate desc LIMIT 100;
派生表1(dt1)为您提供所有日期属性 - 以便按文档的创建日期对结果进行排序。 派生表2为您提供了所有属性..所有由“union all”组合在一起,使您能够按文档分组,然后按创建日期排序。 希望这是正确的方向。