如何从匹配两个相似列的表中选择不同的ID?

时间:2012-09-24 10:22:43

标签: mysql sql

我有这个数据表:

+-----+-----------+------------------------------------+---------+
| ID  | post_type | name                               | term_id |
+-----+-----------+------------------------------------+---------+
| 278 | supplier  | Heating                            |      15 |
| 282 | supplier  | Central Heating                    |      16 |
| 278 | supplier  | Biomass                            |      17 |
| 278 | supplier  | Ground Source Heat Pumps           |      18 |
| 278 | supplier  | Passive Solar                      |      19 |
| 282 | supplier  | Air Source Heat Pumps              |      21 |
| 278 | supplier  | Air Conditioning                   |      22 |
| 278 | supplier  | Boilers                            |      23 |
| 277 | supplier  | Lighting                           |      25 |
| 277 | supplier  | LED's                              |      26 |
| 282 | supplier  | Halogen                            |      28 |
| 277 | supplier  | CFL                                |      29 |
| 282 | supplier  | Sustainable Construction Materials |      31 |
| 282 | supplier  | Plaster                            |      33 |
| 282 | supplier  | Floors                             |      37 |
| 282 | supplier  | Water                              |      38 |
| 282 | supplier  | Showers & Baths                |      43 |
| 278 | supplier  | Cooling                            |      44 |
| 278 | supplier  | Refrigeration                      |      46 |
| 282 | supplier  | Passive Design                     |      47 |
| 278 | supplier  | Chillers                           |      48 |
| 282 | supplier  | Renewable Energy                   |      49 |
| 282 | supplier  | Air Source Heat Pumps              |      53 |
| 282 | supplier  | Biomass Heating                    |      55 |
| 282 | supplier  | Biofuels                           |      57 |
| 282 | supplier  | Insulation                         |      61 |
| 282 | supplier  | Wall                               |      63 |
| 282 | supplier  | Floor                              |      64 |
| 282 | supplier  | Draught Proofing                   |      65 |
| 282 | supplier  | Energy Efficiency                  |      70 |
| 282 | supplier  | Gas Boiler Management Systems      |      71 |
| 282 | supplier  | Low Energy Lighting                |      72 |
| 282 | supplier  | Voltage Control                    |      73 |
| 282 | supplier  | Smart Meters                       |      74 |
| 282 | supplier  | Electric Heating                   |      75 |
+-----+-----------+------------------------------------+---------+

需要提取适用于指定ID(通配符字符串)和name(整数)的term_id列表。例如,我会搜索IDname LIKE '%Lighting%'的{​​{1}},这些term_id = 26应返回ID 277

以下查询有效但不漂亮:

SELECT a.ID, d.name, d.term_id
FROM cn_posts AS a
INNER JOIN cn_postmeta AS b ON a.ID = b.post_id
INNER JOIN cn_term_relationships AS c ON a.ID = c.object_id
INNER JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND d.name LIKE '%Lighting%'
AND a.ID IN (
    SELECT a.ID
    FROM cn_posts AS a
    INNER JOIN cn_postmeta AS b ON a.ID = b.post_id
    INNER JOIN cn_term_relationships AS c ON a.ID = c.object_id
    INNER JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
    WHERE d.term_id = '26'
)
GROUP BY a.ID

我尝试了以下查询,但它们都没有返回任何结果:

SELECT DISTINCT a.ID, d.name, d.term_id
FROM cn_posts AS a
LEFT JOIN cn_postmeta AS b ON a.ID = b.post_id
LEFT JOIN cn_term_relationships AS c ON a.ID = c.object_id
LEFT JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND d.name LIKE '%Lighting%'
AND d.term_id = '26'

SELECT a.ID, d.name, d.term_id, a.post_status
FROM cn_posts AS a
JOIN cn_postmeta AS b ON a.ID = b.post_id
JOIN cn_term_relationships AS c ON a.ID = c.object_id 
JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND d.name LIKE '%Lighting%'
AND d.term_id = '26'
GROUP BY a.ID

这两个回复帖子:

SELECT a.ID, d.name, d.term_id, a.post_status
FROM cn_posts AS a
JOIN cn_postmeta AS b ON a.ID = b.post_id
JOIN cn_term_relationships AS c ON a.ID = c.object_id 
JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND d.name LIKE '%Lighting%'

SELECT a.ID, d.name, d.term_id, a.post_status
FROM cn_posts AS a
JOIN cn_postmeta AS b ON a.ID = b.post_id
JOIN cn_term_relationships AS c ON a.ID = c.object_id 
JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND d.term_id = '26'

但是当你在查询中同时包含name和term_id时,它什么都不返回?

6 个答案:

答案 0 :(得分:1)

显然,表中没有一行(您的数据样本)与d.name LIKE '%Lighting%' AND d.term_id = '26'的条件匹配。有与第一部分匹配的行和与第二部分匹配的行,但没有匹配两者的行。但是,如果将其视为行的,则ID = 277会与条件匹配。因此,您需要引入分组并在HAVING子句中应用条件(尽管稍作修改),如下所示:

SELECT a.ID
FROM cn_posts AS a
INNER JOIN cn_postmeta AS b ON a.ID = b.post_id
INNER JOIN cn_term_relationships AS c ON a.ID = c.object_id
INNER JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
GROUP BY a.ID
HAVING COUNT(d.name LIKE '%Lighting%' OR NULL) > 0
   AND COUNT(d.term_id = '26'         OR NULL) > 0
;

但请注意,这意味着您无法获取d.named.term等详细信息以及同一查询中的ID(但是从a中提取其他列将是全部在这种情况下)。如果返回同一查询中的d列是解决问题所必需的,那么您可能需要在几乎相同的查询中使用上述作为派生表来提取所有数据你需要。在这种情况下,派生表将用作将ID集合过滤到仅匹配两个条件的ID的方法。在该主查询中,这两个条件需要与OR而不是AND相关联,如下所示:

SELECT a.ID, d.name, d.term_id
FROM cn_posts AS a
INNER JOIN cn_postmeta AS b ON a.ID = b.post_id
INNER JOIN cn_term_relationships AS c ON a.ID = c.object_id
INNER JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND (d.name LIKE '%Lighting%' OR d.term_id = '26')
AND a.ID IN (
    /* the above query, now used just as a filter */
    SELECT a.ID
    FROM cn_posts AS a
    INNER JOIN cn_postmeta AS b ON a.ID = b.post_id
    INNER JOIN cn_term_relationships AS c ON a.ID = c.object_id
    INNER JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
    WHERE a.post_status = 'publish'
    GROUP BY a.ID
    HAVING COUNT(d.name LIKE '%Lighting%' OR NULL) > 0
       AND COUNT(d.term_id = '26'         OR NULL) > 0
)
;

显然,这几乎不会比你最终的查询更好。

答案 1 :(得分:0)

你试过这个吗?

SELECT a.ID, d.name, d.term_id
FROM cn_posts AS a
INNER JOIN cn_postmeta AS b ON a.ID = b.post_id
INNER JOIN cn_term_relationships AS c ON a.ID = c.object_id 
INNER JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND d.name LIKE '%Lighting%'
AND d.term_id = '28'
GROUP BY a.ID

答案 2 :(得分:0)

SELECT a.ID, d.name, d.term_id, a.post_status
FROM wp_posts AS a
JOIN wp_postmeta AS b ON a.ID = b.post_id
JOIN wp_term_relationships AS c ON a.ID = c.object_id 
JOIN wp_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND d.name LIKE '%Halogen%'
AND d.term_id = '25'
GROUP BY a.ID

答案 3 :(得分:0)

这个简单的选择不能做你需要的。

select ID, name, term_id from yourtable where name LIKE '%Lighting%' and a term_id = 26

答案 4 :(得分:0)

在得到所有人的帮助之后(非常感谢!!)我最后只是使用了这个查询,这个查询不是最干净但是唯一一个得到了我所追求的结果的查询,我需要让工作顺利进行。< / p>

还匹配帖子标题和说明上的关键字以及服务名称。

SELECT a.ID, a.post_title, a.post_status, d.name, d.term_id
FROM cn_posts AS a
JOIN cn_postmeta AS b ON a.ID = b.post_id
JOIN cn_term_relationships AS c ON a.ID = c.object_id
JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
WHERE a.post_status = 'publish'
AND ( a.post_title LIKE '%Lighting%' OR a.post_content LIKE '%Lighting%' OR d.name LIKE '%Lighting%' )
AND a.ID IN (
    SELECT a.ID FROM cn_posts AS a
    INNER JOIN cn_postmeta AS b ON a.ID = b.post_id
    INNER JOIN cn_term_relationships AS c ON a.ID = c.object_id
    INNER JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id
    WHERE d.term_id = '26' )
GROUP BY a.ID

非常感谢你的帮助。显然,如果你能弄清楚为什么其他查询不起作用或者可以清理这个查询,请随时回复。

戴夫

答案 5 :(得分:0)

SELECT a.ID, d.name, d.term_id 
FROM cn_posts AS a 
INNER JOIN cn_postmeta AS b ON a.ID = b.post_id 
INNER JOIN cn_term_relationships AS c ON a.ID = c.object_id 
INNER JOIN cn_terms AS d ON c.term_taxonomy_id = d.term_id 
INNER JOIN cn_terms AS d2 ON c.term_taxonomy_id = d2.term_id 
WHERE a.post_status = 'publish' 
AND d.name LIKE '%Lighting%' 
AND d2.term_id = '26' 

由于您的条件位于不同的行,因此您必须两次加入cn_terms。