MySQL在联接表上应用筛选器

MySQL在联接表上应用筛选器,mysql,sql,join,filter,Mysql,Sql,Join,Filter,假设我们有一个具有物理长方体的数据库,定义为对象。每个对象都有长度、宽度和高度。如下面的示例所示 CREATE TABLE dimensions( id int PRIMARY KEY NOT NULL, value int ); CREATE TABLE object( id int, dimension VARCHAR(100), dimension_value_id int, FOREIGN KEY (dimension_value_id)

假设我们有一个具有物理长方体的数据库,定义为对象。每个对象都有长度、宽度和高度。如下面的示例所示

CREATE TABLE dimensions(
    id int PRIMARY KEY NOT NULL,
    value int
);

CREATE TABLE object(
    id int,
    dimension VARCHAR(100),
    dimension_value_id int,
    FOREIGN KEY (dimension_value_id) REFERENCES dimensions(id)
);

INSERT INTO dimensions VALUES(0, 100);
INSERT INTO dimensions VALUES(1, 200);
INSERT INTO dimensions VALUES(2, 300);
INSERT INTO dimensions VALUES(3, 400);

INSERT INTO object VALUES(0, "length", 1);
INSERT INTO object VALUES(0, "width", 3);
INSERT INTO object VALUES(0, "height", 2);

INSERT INTO object VALUES(1, "length", 1);
INSERT INTO object VALUES(1, "width", 1);
INSERT INTO object VALUES(1, "height", 2);
我的目标是筛选维度小于251x25x350的对象,在示例中,这是id为1的对象

加入表格时,我会得到以下记录:

SELECT * FROM object o
JOIN dimensions d ON o.dimension_value_id = d.id
但是现在如何应用过滤器呢。我遇到了一个具有exists/notexists的解决方案。但在这种情况下,这将不起作用,因为我需要有一个不存在的排他性。
如何实现这一点?

您可以使用条件聚合。这看起来像:

SELECT o.id 
FROM object o JOIN
     dimensions d 
     ON o.dimension_value_id = d.id
GROUP BY o.id 
HAVING MAX(CASE WHEN o.dimension = 'length' THEN d.value END)) < 350 AND
       MAX(CASE WHEN o.dimension = 'width' THEN s.value END)) < 350 AND
       MAX(CASE WHEN o.dimension = 'height' THEN d.value END)) < 350;
选择o.id
从对象到连接
尺寸d
关于o.dimension\u value\u id=d.id
按o.id分组
最大值(o.dimension='length'然后d.value END)小于350,且
最大值(o.dimension=‘width’然后s.value END时的情况)<350和
最大值(o.尺寸=‘高度’然后d.值结束时的情况)<350;

您可以使用条件聚合。这看起来像:

SELECT o.id 
FROM object o JOIN
     dimensions d 
     ON o.dimension_value_id = d.id
GROUP BY o.id 
HAVING MAX(CASE WHEN o.dimension = 'length' THEN d.value END)) < 350 AND
       MAX(CASE WHEN o.dimension = 'width' THEN s.value END)) < 350 AND
       MAX(CASE WHEN o.dimension = 'height' THEN d.value END)) < 350;
选择o.id
从对象到连接
尺寸d
关于o.dimension\u value\u id=d.id
按o.id分组
最大值(o.dimension='length'然后d.value END)小于350,且
最大值(o.dimension=‘width’然后s.value END时的情况)<350和
最大值(o.尺寸=‘高度’然后d.值结束时的情况)<350;

必须将3个维度中较小的维度与3个值中较小的维度进行比较,将最大维度与3个值中最大的维度进行比较,将中间维度与3个值中的中间维度进行比较:

select o.id 
from object o inner join dimensions d 
on o.dimension_value_id = d.id
group by o.id 
having 
  min(d.value) < least(251, 251, 350) 
  and 
  max(d.value) < greatest(251, 251, 350)
  and
  max(case when o.dimension = 'length' then d.value end) + 
  max(case when o.dimension = 'width' then d.value end) +
  max(case when o.dimension = 'height' then d.value end) -
  (min(d.value) + max(d.value)) < 
  (251 + 251 + 350) - (least(251, 251, 350) + greatest(251, 251, 350))

请参见。

您必须将3个维度中较小的维度与3个值中较小的维度进行比较,将最大维度与3个值中最大的维度进行比较,将中间维度与3个值中的中间维度进行比较:

select o.id 
from object o inner join dimensions d 
on o.dimension_value_id = d.id
group by o.id 
having 
  min(d.value) < least(251, 251, 350) 
  and 
  max(d.value) < greatest(251, 251, 350)
  and
  max(case when o.dimension = 'length' then d.value end) + 
  max(case when o.dimension = 'width' then d.value end) +
  max(case when o.dimension = 'height' then d.value end) -
  (min(d.value) + max(d.value)) < 
  (251 + 251 + 350) - (least(251, 251, 350) + greatest(251, 251, 350))

请参见。

这些可能是长方体,但它们不是正方形?!?!?顺便说一句,INT声明后括号中的数字几乎完全没有意义——这在本例中也是一样的,因为所描述的允许数将大于宇宙中的原子数。与什么相比更小?所有尺寸或体积?与所有尺寸进行比较。方向也应该被忽略,这意味着如果需要达到更小的条件,我想要旋转,独立于原始方向。这是否意味着对象的3个维度中的较大者必须小于3:251x25x350中的较小者,因此251可以旋转对象?假设我们有一个大小为250x250x300的对象,希望检查是否可以将其放入大小为251x25x350的框中。所以我们可以自由旋转,但我们不能。意味着如果给定的框是251x350x251或350x251x251,我也希望安装它。你明白我的意思吗?这些可能是长方体,但它们不是正方形?!?!?顺便说一句,INT声明后括号中的数字几乎完全没有意义——这在本例中也是一样的,因为所描述的允许数将大于宇宙中的原子数。与什么相比更小?所有尺寸或体积?与所有尺寸进行比较。方向也应该被忽略,这意味着如果需要达到更小的条件,我想要旋转,独立于原始方向。这是否意味着对象的3个维度中的较大者必须小于3:251x25x350中的较小者,因此251可以旋转对象?假设我们有一个大小为250x250x300的对象,希望检查是否可以将其放入大小为251x25x350的框中。所以我们可以自由旋转,但我们不能。意味着如果给定的框是251x350x251或350x251x251,我也希望安装它。你明白我的意图吗?