MySQL多表搜索

时间:2014-05-23 07:49:54

标签: mysql sql

我正在创建一个人们可以上传课程的在线商店。

我的表结构是

products - (contains basic lesson information)
p_tags - id|productid|tag - (contains all tags related to a product)
p_subjects - id|subjectid|productid - (contains all subjects related to a product)
p_years - id|yearid|productid - (contains all years related to a product)
p_types - id|typeid|productid - (contains all subjects related to a product)
subjects - id|name - (contains all subjects links to p_subjects)
resourcetypes - id|name - (contains all product types links to p_types)
years - id|name - (contains all years links to p_years)

我要做的是编写一个可以根据用户搜索条件生成relevance分数的查询。这就是我到目前为止所做的:

SELECT 
IFNull(a.matchedTags,0) AS matchedtags,
a.title,
IFNull(b.matchedSubjects,0) AS matchedsubjects,
IFNull(c.matchedYears,0) AS matchedyears,
IFNull(d.matchedTypes,0) AS matchedtypes                    
FROM
(
SELECT
z.*,
COUNT(*) AS matchedTags
FROM products z
INNER JOIN p_tags pt ON pt.productid = z.id
WHERE 
pt.tag IN('foo','test')
GROUP BY z.id
HAVING COUNT( * ) > 0
) as a

LEFT JOIN (
SELECT
y.*,
COUNT(*) AS matchedSubjects
FROM products y
WHERE
3 IN (SELECT subjectid FROM p_subjects m WHERE m.productid = y.id)
GROUP BY y.id
HAVING COUNT( * ) > 0
) as b ON b.id=a.id

LEFT JOIN (
SELECT
x.*,
COUNT(*) AS matchedYears
FROM products x
WHERE
1 IN (SELECT yearid FROM p_years n WHERE n.productid = x.id)
GROUP BY x.id
HAVING COUNT( * ) > 0
) as c ON c.id=b.id

LEFT JOIN (
SELECT
w.*,
COUNT(*) AS matchedTypes
FROM products w
WHERE
1 IN (SELECT id FROM p_types o WHERE o.productid = w.id)
GROUP BY w.id
HAVING COUNT( * ) > 0
) as d ON d.id=c.id

查询运行正常,但只有满足以前的条件才会匹配产品。即,如果产品有标签' foo'然后它将获得匹配的主题数量的值。如果产品不包含标签,则对于所有后续JOINS,它将返回0。

我猜测我使用了错误的联接,并使用LEFT AND RIGHT然后使用UNION查看了OUTER JOIN,但不知道如何将其放入此代码中以及是否会无论如何工作。

提前致谢

1 个答案:

答案 0 :(得分:0)

真是个白痴!!我加入了彼此之上的联接,所以它只是添加到上面的标准。我现在已经改变它并且工作甜美!!

SELECT
    g.title,
    g.id, 
    IFNull(a.matchedTags,0) AS matchedtags,
    IFNull(b.matchedSubjects,0) AS matchedsubjects,
    IFNull(c.matchedYears,0) AS matchedyears,
    IFNull(d.matchedTypes,0) AS matchedtypes                    
    FROM
    (SELECT id,title FROM products) as g

    LEFT JOIN (
    SELECT
    z.*,
    COUNT(*) AS matchedTags
    FROM products z
    INNER JOIN p_tags pt ON pt.productid = z.id
    WHERE 
    pt.tag IN('test')
    GROUP BY z.id
    ) as a on a.id=g.id

    LEFT JOIN (
    SELECT
    y.*,
    COUNT(*) AS matchedSubjects
    FROM products y
    WHERE
    5 IN (SELECT subjectid FROM p_subjects m WHERE m.productid = y.id)
    GROUP BY y.id
    ) as b ON b.id=g.id

    LEFT JOIN (
    SELECT
    x.*,
    COUNT(*) AS matchedYears
    FROM products x
    WHERE
    1 IN (SELECT yearid FROM p_years n WHERE n.productid = x.id)
    GROUP BY x.id
    ) as c ON c.id=g.id

    LEFT JOIN (
    SELECT
    w.*,
    COUNT(*) AS matchedTypes
    FROM products w
    WHERE
    1 IN (SELECT id FROM p_types o WHERE o.productid = w.id)
    GROUP BY w.id
    ) as d ON d.id=g.id
相关问题