2010-03-24 41 views
1

我创建一个“同类项”链接表。Mysql的选择带有或跨2列

我有一个2列的表。两列都包含产品ID。

CREATE TABLE IF NOT EXISTS `prod_similar` (
    `id_a` int(11) NOT NULL, 
    `id_b` int(11) NOT NULL 
)  

INSERT INTO `prod_similar` (`id_a`, `id_b`) VALUES 
(5, 10), 
(5, 15), 
(10, 13), 
(10, 14), 
(14, 5), 
(14, 13); 

我想选择3种类似的产品,有利于产品,该ID是在第一个关口, 'ID_A'

SELECT * FROM prod_similar WHERE id_a={$id} OR id_b={$id} 
ORDER BY column(?) 
LIMIT 3 

回答

2

我假设你有其他列以及

(SELECT 1 favouring, id_a id, [other columns] 
FROM prod_similar 
WHERE id_a = {$id}) 
UNION 
(SELECT 2 favouring, id_b id, [other columns] 
FROM prod_similar 
WHERE id_b = {$id}) 
ORDER BY favouring, id 
LIMIT 3; 

如果你不介意重复或有ID_A之间没有和ID_B你可以做UNION ALL代替这是相当快。

联盟非正规化数据的指示,非规范化数据提高某些查询的速度,并减少其他(如此)的速度。

+0

没有其他列 – Haroldo 2010-03-24 13:10:19

+0

@goran,这看起来很不错,除了确保在SELECT语句周围添加括号以便ORDER子句出现在最终结果集上。将AS关键字用于别名也会使其更具可读性。 – 2010-03-24 13:59:51

+0

@marcus,我添加括号,http://dev.mysql.com/doc/refman/5.1/en/union.html上的文档说这样做(对于LIMIT也是如此)。至于别名,不,对我来说,没有它就更具可读性。 – Unreason 2010-03-24 14:21:18

3

不知道,也许这?

SELECT * 
FROM similar_items 
WHERE col_1={$id} OR col_2={$id} 
ORDER BY CASE WHEN col_1={$id} THEN 0 WHEN col_2={$id} THEN 1 END 
LIMIT 3 
1

我不知道我得到的问题,你可能会张贴源表的示例数据,并显示结果应该是什么样子。

如果我有你的权利,我会尝试像

Select (case 
    when col_1={$ID}: 
    col1 
    when col_2={$ID}: 
    col2) as id from similar_items WHERE col_1={$id} OR col_2={$id} 
LIMIT 3 
2

一个简单的方法来做到这一点是这样的:

ORDER BY NULLIF(col_1, {$id}) LIMIT 3 

时,作为好,但这是有点简单的情况。

+0

即时试图找到对NULLIF().. 又有什么本质上做一些文档? 我已经重新解释了我的问题,现在应该更有意义了! – Haroldo 2010-03-24 13:02:14

+0

如果第一个参数等于第二个参数,则NULLIF返回NULL。在这种情况下,如果COL_1等于你的说法,它将返回NULL,把第一的顺序由 – 2010-03-24 13:09:11

+0

的Jhonny打我吧:) NULLIF()如果第一和第二个参数是相同的返回NULL,否则返回第一个参数。简而言之,这意味着如果col_1是产品ID,则返回NULL,否则返回col_1中的任何内容。在升序排序中,NULL值始终首先出现,因此这将优先考虑col_1中具有产品ID的行。 – 2010-03-24 13:09:29