The Design Pattern you are looking for is Query Object:
An object that represents a database query.
SQL can be an involved language, and many developers aren't particularly familiar with it. Furthermore, you need to know what the database schema looks like to form queries. You can avoid this by creating specialized finder methods that hide the SQL inside parameterized methods, but that makes it difficult to form more ad hoc queries. It also leads to duplication in the SQL statements should the database schema change.
A Query Object is an interpreter [Gang of Four], that is, a structure of objects that can form itself into a SQL query. You can create this query by referring to classes and fields rather than tables and columns. In this way those who write the queries can do so independently of the database schema and changes to the schema can be localized in a single place.
When you use a Query Object, there will be no SQL on the public API at all. The transformation of the Query Object into your DB vendor's appropriate SQL will happen under the hood. This will involve writing appropriate Adapters and is not limited to SQL Databases then.
A alternative would be to use something like Zend_Db_Select
, which is an internal DSL for creating SQL queries.
Example from ZF Reference Guide:
$select = $db->select()
->from( ...specify table and columns... )
->where( ...specify search criteria... )
->order( ...specify sorting criteria... );
But while Zend_Db_Select
(and PDO mentioned elsewhere) abstract access to the used DB system to some degree, they still require you to know SQL and table structures. Unlike Query Object, using a DB abstraction layer like this does not guarantee portability.
Depending on what arguments you put into these methods, you may end up with Queries that wont be portable anymore, e.g. when you use a specific DB vendor's dialect or functions in the queries.
So which to pick depends on your queries. If you know you only have standard queries, don't use Query Object because it is much more effort to implement. Use Query Object if you want maximum independence from the data source.