2015-09-08 27 views
0

我试图根据他们的请求向我的用户提供一些资源。通过选择选项向请求建议某些资源的SQL查询

这里是我的5台的资源和他们的选择和要求,选择的选项

Resource  res_opt_junc Options req_opt_junc Request 
--------- ------------ ------- ------------ -------- 
Res_id  res_id   opt_id  req_id   Req_id 
      opt_id      opt_id     

我收到请求,并根据用户选择的选项,我想是能够满足要求的用户选择的选项资源。

为了简化,我希望资源至少具有所有请求选择的选项。

一些样本数据应该是这样的

Resource  res_opt_junc  Options   req_opt_junc  Request 
---------- ------------  ------------  ------------- -------- 
id name  res_id opt_id opt_id name  req_id opt_id  req_id 
1 class1  1  1  1  internet  1  1   1 
       1  2  2  projector 1  2   

2 class2  2  1        2  1   2 

所以这里是一些数据, 例如,如果用户需要的必须选项1(互联网)类和2(投影机)我需要建议的Class1但不是CLASS2只能有选择的请求数量选择用户后OP的评论1

+0

你是如何通过所选择的选择? –

+0

所选选项进入req_opt_junc(联结)表。 –

+0

你能提供一些样品数据和预期结果吗? –

回答

0

编辑之一:

这现在已经成为关系与余下的部门。这是解决这个的一种方法:

SELECT r.id, r.name 
FROM res_opt_junc ro 
INNER JOIN(
    SELECT opt_id 
    FROM res_opt_junc 
    WHERE res_id = @req_id 
)t 
    ON t.opt_id = ro.opt_id 
INNER JOIN Resource r 
    ON r.id = ro.res_id 
GROUP BY r.id, r.name 
HAVING 
    COUNT(t.opt_id) = (
     SELECT COUNT(*) 
     FROM res_opt_junc 
     WHERE res_id = @req_id 
    ) 

另一种解决方案:

DECLARE @req_id INT = 1 

DECLARE @opts TABLE(opt_id INT PRIMARY KEY); 
INSERT INTO @opts 
    SELECT opt_id 
    FROM req_opt_junc 
    WHERE req_id = @req_id 

SELECT r.* 
FROM (
    SELECT 
     res_id, cnt = COUNT(DISTINCT opt_id) 
    FROM res_opt_junc 
    WHERE opt_id IN(SELECT opt_id FROM @opts) 
    GROUP BY res_id 
)a 
INNER JOIN Resource r 
    ON r.id = a.res_id 
WHERE 
    a.cnt = (SELECT COUNT(*) FROM @opts) 

我相信这是一个Relational Division with no Remainder (RDNR)问题。

SQL Fiddle

这里是解决这个的一种方法:

DECLARE @req_id INT = 1 

DECLARE @opts TABLE(opt_id INT PRIMARY KEY); 
INSERT INTO @opts 
    SELECT opt_id 
    FROM req_opt_junc 
    WHERE req_id = @req_id 

SELECT r.* 
FROM (
    SELECT 
     res_id, cnt = COUNT(DISTINCT opt_id) 
    FROM res_opt_junc 
    WHERE opt_id IN(SELECT opt_id FROM @opts) 
    GROUP BY res_id 
)a 
INNER JOIN Resource r 
    ON r.id = a.res_id 
WHERE 
    a.cnt = (SELECT COUNT(*) FROM @opts) 
    AND a.cnt = (
     SELECT COUNT(*) 
     FROM res_opt_junc 
     WHERE res_id = a.res_id 
    ) 

如果你不想使用表变量:

SELECT r.* 
FROM (
    SELECT 
     res_id, cnt = COUNT(DISTINCT opt_id) 
    FROM res_opt_junc 
    WHERE opt_id IN(
     SELECT opt_id 
     FROM req_opt_junc 
     WHERE req_id = @req_id 
    ) 
    GROUP BY res_id 
)a 
INNER JOIN Resource r 
    ON r.id = a.res_id 
WHERE 
    a.cnt = (
     SELECT COUNT(*) 
     FROM req_opt_junc 
     WHERE req_id = @req_id 
    ) 
    AND a.cnt = (
     SELECT COUNT(*) 
     FROM res_opt_junc 
     WHERE res_id = a.res_id 
    ) 
+0

谢谢你,我只是测试你的查询和它的工作,我会再测试一下,稍后我会通知你 –

+0

没问题。一定要阅读文章。另外,使用'''而不是'作为撇号。 –

+0

对不起,但这不起作用,我不需要一个完全匹配,我需要资源,满足要求,他们也许有更多的选择,但至少他们有要求的选项 –

0
SELECT res_id FROM req_opt_junc AS rqoj 
LEFT JOIN res_opt_junc AS rsoj ON rsoj.opt_id = rqoj.opt_id 
WHERE rqoj.req_id = "request id goes here" 
AND rqoj.opt = "option id goes here" 
+0

谢谢,但我试过这之前它显示每个资源有一个请求的选项,我需要资源,让每个用户选择请求中的选项。 –

+0

@M塔赫,你需要两个输入?一个是请求ID,另一个是选项ID? –

+0

@Mather,再次,样本数据和预期的结果将有助于澄清您的问题/ –