好的,我一直试图为此寻找解决方案,虽然不是很完美,但我有点做了,我觉得可能会有更好的解决方案。
这有点棘手,我有3张桌子 -
购物车 -
id | name
----------
1 | x
.. | ..
cart_items -
cart_id | item_id
------------------
1 | 1
1 | 2
2 | 1
2 | 3
项目 -
id | color | shape | size | ...
-------------------------------
1 | blue | round | big | ...
2 | * | rect | small| ...
3 | red | * | big | ...
(此表具有与任何选项匹配的通配符)
现在有很多关系,到目前为止没什么特别的 我得到的输入是一组特征(颜色,形状,大小等)的列表,我需要带有那些符合这些特征的相关购物车。
例如 - 用户查询包含2个项目的购物车 -
一个是大而蓝的
秒是小而圆的
我所做的是获取与第一项要求匹配的项目ID列表以及与第二项目匹配的另一个列表。
有了这两个列表,我应该查询一个购物车,其中有2个项目符合这些特征(至少)。
让我们说我从这个查询中收到了两个项目清单 -
对于第一个 - (1,3,5,6,7)
对于第二个 - (3,4,7,9,15)
确保我的购物车有2个项目的最佳查询是什么,一个来自第一个列表,另一个来自第二个列表。我应该说项目数量可以超过2个。
我找到的解决方案是连接' EXISTS'条件,像这样 -
SELECT DISTINCT(cart_id) FROM cart_items ci WHERE
EXISTS(SELECT 1 FROM cart_items WHERE cart_id = ci.cart_id AND item_id IN <list 1>)
AND EXISTS(SELECT 1 FROM cart_items WHERE cart_id = ci.ci_cart_id AND item_id IN <list 2>)
AND ...<keep concatenating as long as needed>
很抱歉有长篇描述,有什么建议吗?
答案 0 :(得分:1)
如果您将查询本身建模为表格,这会有所简化(但是对于您将生成查询的最佳解决方案 - 但使用SQL创建SQL不适合胆小的人,并且您没有标记此用任何其他语言)。因此...
CREATE TABLE queries (
query_id INTEGER NOT NULL,
color VARCHAR (20),
shape VARCHAR (20),
size VARCHAR (20),
PRIMARY KEY (query_id, color, shape, size)
);
INSERT INTO queries (query_id, color, shape, size)
VALUES (1, 'blue', '*', 'big');
INSERT INTO queries (query_id, color, shape, size)
VALUES (2, '*', 'round', 'small');
然后您可以通过以下方式识别匹配的项目:
SELECT i.id
FROM items i
INNER JOIN queries q
ON q.color IN (i.color, '*')
AND q.size IN (i.size, '*')
AND q.shape IN (i.shape, '*')
WHERE q.query_id=1;
然后你只需要将它加入cart_items以获得匹配的购物车......
SELECT q.query_id, ci.cart_id
FROM items i
INNER JOIN queries q
ON q.color IN (i.color, '*')
AND q.size IN (i.size, '*')
AND q.shape IN (i.shape, '*')
INNER JOIN cart_items ci
ON i.id=ci.item_id
WHERE q.query_id IN (1,2);
最后,您只需要识别与两个查询匹配的cart_ids:
SELECT COUNT(DISTINCT q.query_id), ci.cart_id
FROM items i
INNER JOIN queries q
ON q.color IN (i.color, '*')
AND q.size IN (i.size, '*')
AND q.shape IN (i.shape, '*')
INNER JOIN cart_items ci
ON i.id=ci.item_id
WHERE q.query_id IN (1,2)
HAVING COUNT(DISTINCT q.query_id)=2;