2009-11-15 60 views
1

我想在语句中使用通配符的一切之下:野生表达式语句

"SELECT threads.* 
    FROM thread_tag_map, threads, tags 
    WHERE thread_tag_map.thread_id = threads.id 
    AND thread_tag_map.tag_id = tags.id 

    AND (tags.name IN ('WILDCARD'))"; 

我应该更换,以能够选择每个条目通配符?我试过('*'),但那不起作用。

我可以放弃最后一行,但事情是,我正在做这个功能。传递一个值可以说$value,而$value将取代WILDCARD。所以当我通过'计算机'为$value它会得到所有行的计算机,但我希望能够通过任何东西,默认$value将是一个通配符来选择一切。那么我怎么能使这成为可能?

回答

4

我建议使用MySQL's Prepared Statements动态构造你想要的SQL语句。这里有一个例子:

SET @SQL := 'SELECT th.* 
       FROM THREADS th 
       JOIN THREAD_TAG_MAP ttm ON ttm.thread_id = th.id 
       JOIN TAGS t ON t.id = ttm.tag_id ' 

IF @tag_name IS NULL THEN 

    PREPARE stmt FROM @SQL; 
    EXECUTE stmt; 

ELSE 

    SET @SQL := @SQL + ' WHERE t.name LIKE ''%'+ @tag_name +'%''' 
    PREPARE stmt FROM @SQL; 
    EXECUTE stmt USING @tag_name; 

END IF; 
+0

这种方法还支持以逗号分隔的标记名列表作为字符串IN子句中,由于是一个字符串,所以在执行之前将现有SQL查询连接起来没有任何问题。 – 2009-11-15 01:01:43

+0

忘记提及我将查询更改为使用ANSI JOIN – 2009-11-15 01:19:10

+0

+1,th尽管这可能是过度杀伤,除非OP的预期“功能”实际上是一个存储过程 - 检查和准备/执行都可以(并且可能更容易)以他使用的任何语言完成。 – ChssPly76 2009-11-15 01:19:44

2

如果你真的想选择每个条目,共下降了最后一个条件:

SELECT threads.* 
    FROM thread_tag_map, threads, tags 
WHERE thread_tag_map.thread_id = threads.id 
    AND thread_tag_map.tag_id = tags.id 

更新(基于问题的更新)。由于您似乎在动态构建SQL,因此您可以检查标记值中传入的值是否为空(或者您指定为“通配符”的任何值),然后仅省略“AND tags.name ='value'”条件。或者,如果通过“函数”来表示MySQL的存储过程,请查看OMG Ponies的解决方案。

0

您可能想要使用LIKE,它允许%和_通配符。 IN测试包含在一组值中。

SELECT threads.* 
     FROM thread_tag_map, threads, tags 
     WHERE thread_tag_map.thread_id = threads.id 
     AND thread_tag_map.tag_id = tags.id 

     AND tags.name LIKE '%foo_bar%'; 
+0

我应该如何键入它,然后,如果我想和喜欢的方式使用它? – ajsie 2009-11-15 00:41:26

+0

简单的一种是tags.name像” %',它捕获每个非空值 – Thorsten 2009-11-15 00:44:31

+0

我希望他的问题并不是真正的选择所有(不是NULL)值。谁知道,尽管... – Dmitry 2009-11-15 00:53:38

0
SELECT threads.* 
FROM thread_tag_map, threads, tags 
WHERE 1=1 
AND thread_tag_map.thread_id = threads.id 
AND thread_tag_map.tag_id = tags.id 
AND tags.name != '' 

也许查询像这样,在您检查如果不是空白?那或者丢掉最后的AND

0

SELECT threads.*正在选择每一列。要选择的每一行,你需要删除最后一个WHERE条件:

这将选择所有列和行:

SELECT threads.* FROM thread_tag_map, threads, tags 
    WHERE thread_tag_map.thread_id = threads.id 
    AND thread_tag_map.tag_id = tags.id 
1

首先,我想你可能会误解IN子句。在让你给匹配的项目清单:

SELECT * FROM [table] WHERE name IN ('Joe','Moe','Larry) 


正如其他人所提到LIKE将使模式匹配,以%为多字符通配符(*在其他语言中,%在这里) 。

SELECT * FROM [table] WHERE name LIKE '%oe' 


我假设你的情况$值由用户稀少,所以可以为空白。在这种情况下,你想要“一切”。在过度简化的例子,这是种OGF的事情我在过去所做的:

SELECT * FROM [table] WHERE (name LIKE @pattern OR @pattern = '') 


正如你似乎是构建SQL字符串,最多的应用,另一种方法是如果[LEN($ value)> 0]只包含最终的WHERE条件。

另请注意,如果您正在从用户处取得一个字符串并将其嵌入到SQL中执行,请确保使用任何您必须使该字符串安全的方法。你并不是真的想让别人去搜索以下字符串...

  • '));删除标记WHERE(名称NOT IN(“

SQL注入是baaad,mmmkay?