查询通过嵌套外部引用检索实体

时间:2018-01-24 17:39:23

标签: sql join foreign-keys

想象一下,您有以下数据库模式( FK约束被省略;我希望parent->子关系对您来说很明显,可以从列名推断出来):

CREATE TABLE entity (
  ID INT PRIMARY KEY NOT NULL,
  NAME VARCHAR(255) NOT NULL
);

CREATE TABLE property (
  ID   INT PRIMARY KEY NOT NULL,
  NAME VARCHAR(255)    NOT NULL
);

CREATE TABLE property_value (
  ID          INT PRIMARY KEY NOT NULL,
  ENTITY_ID   INT             NOT NULL,
  PROPERTY_ID INT             NOT NULL,
  VALUE       TEXT
);

如何从db中获取符合以下样本条件的所有实体

propertyName1 = propertyValue1 AND propertyName2 = propertyValue2
OR propertyName3 = propertyValue3

更具体的例子:

Entity entity = new Entity();
entity->setName("t-short")
entity->addProperty("color", "red");
entity->addProperty("time", "14:32");
entity->addProperty("size", "xxl");

如何按color = red AND time > 14:30

获取所有实体

2 个答案:

答案 0 :(得分:1)

SELECT entity.ID
FROM entity
INNER JOIN property_value AS color_value ON color_value.ENTITY_ID = entity.ID 
INNER JOIN property AS color ON color_value.property_id=color.ID
INNER JOIN property_value AS time_value ON time_value .ENTITY_ID = entity.ID 
INNER JOIN property AS time ON time.property_id=color.ID
WHERE time.name="time" AND color.name="color"
AND time_value.VALUE > "14:13" AND color_value = "red"

答案 1 :(得分:0)

时间过滤器会出现严重问题,因为您已将值存储为文本,而不是时间感知。但是,对于您的滤镜,您可以这样做:

select *
from entity as e
join property_value as pv
on e.id = pv.entity_id
join property as p
on p.id = pv.property_id
where p.name = 'color'
and pv.value = 'red'

添加其他标准应该非常简单:

or p.name = 'size'
and pv.value = 'xxl'

时间问题是字符字段使用字符比较规则,因此'2:00'大于'14:32',因为字符是单独比较而'2'大于'1',角色的放置没有意义,而datetime&数字列使用数字的重要性作为比较的一部分(例如10或100s数字)。

'1:'小于'14',因为':'在字符代码序列中小于'4',而不是因为1< 14。