PT Português
Versão: v2.3.0

select

Recuperar dados de uma tabela.

select($table, $columns)
select($table, $columns, $where)
select($table, $join, $columns, $where)
Valor de retorno
[array] Um array contendo as linhas recuperadas.
Você pode usar * no parâmetro columns para recuperar todas as colunas; ainda assim, por desempenho e legibilidade, o ideal é informar explicitamente apenas as colunas necessárias.
$data = $database->select("account", [
	"user_name",
	"email"
], [
	"user_id[>]" => 100
]);

// Resultado de exemplo:
// array(
//  [0] => array(
//	  "user_name" => "foo",
//	  "email" => "foo@bar.com"
//  ),
//  [1] => array(
//	  "user_name" => "cat",
//	  "email" => "cat@dog.com"
//  )
// )

foreach ($data as $item) {
	echo "Usuário: " . $item["user_name"] . " - E-mail: " . $item["email"] . "<br/>";
}

// Seleciona todas as colunas.
$data = $database->select("account", "*");

// Seleciona uma única coluna.
$data = $database->select("account", "user_name");

// Resultado de exemplo:
// array(
//  [0] => "foo",
//  [1] => "cat"
// )

Recuperando linhas com callback

Por padrão, select() carrega o conjunto completo de resultados na memória e o retorna como um array.
Ao recuperar um grande número de linhas, isso pode aumentar significativamente o uso de memória. Se você passar um retorno de chamada como function ($data) {} como o último argumento para select(), Medoo irá buscar e processar cada linha imediatamente em vez de armazenar primeiro todo o conjunto de resultados na memória.
Essa abordagem é mais eficiente em termos de memória ao trabalhar com grandes conjuntos de dados.
$database->select("account", ["name"], function ($data) {
	echo $data["name"];
});

$database->select("account", [
	"name"
], function ($data) {
	echo $data["name"];
});
Benchmark de desempenho
O exemplo a seguir compara o uso de memória ao buscar e gerar 1.000, 5.000 e 20.000 linhas de um banco de dados MySQL. O uso de memória é medido com memory_get_usage().
// Método 1
$database->select("account", ["name"], function ($data) {
	echo $data["name"];
});

// Compare com:

// Método 2
$data = $database->select("account", ["name"]);

foreach ($data as $item) {
	echo $item["name"];
}
Método 1 Método 2
1.000 registros 789 KB 1,2 MB
5.000 registros 1,1 MB 3,3 MB
20.000 registros 2,26 MB 11,1 MB

Joins de tabelas

As cláusulas SQL JOIN combinam linhas de várias tabelas. Medoo fornece uma sintaxe simples para construir junções.
$database->select("post", [
	// Define a relacao entre a tabela principal e a tabela associada.
	"[>]account" => ["author_id" => "user_id"]
], [
	"post.title",
	"account.city"
]);
A coluna author_id na tabela post corresponde à coluna user_id na tabela account.
"[>]account" => ["author_id" => "user_id"]
LEFT JOIN "account" ON "post"."author_id" = "account"."user_id"
Se ambas as tabelas usarem o mesmo nome de coluna, você poderá usar o formato abreviado.
"[>]album" => "user_id"
LEFT JOIN "album" USING ("user_id")
Se várias colunas compartilharem os mesmos nomes em ambas as tabelas, você poderá passá-las como uma matriz.
"[>]photo" => ["user_id", "avatar_id"]
LEFT JOIN "photo" USING ("user_id", "avatar_id")
Se você precisar ingressar na mesma tabela mais de uma vez, atribua um alias à tabela associada.
"[>]account (replier)" => ["replier_id" => "user_id"]
LEFT JOIN "account" AS "replier" ON "post"."replier_id" = "replier"."user_id"
Você também pode fazer referência a uma tabela unida anteriormente prefixando a coluna com o nome da tabela.
"[>]account" => ["author_id" => "user_id"],
"[>]album" => ["account.user_id" => "user_id"]
LEFT JOIN "account" ON "post"."author_id" = "account"."user_id"
LEFT JOIN "album" ON "account"."user_id" = "album"."user_id"
Múltiplas condições JOIN
"[>]account" => [
	"author_id" => "user_id",
	"album.user_id" => "user_id"
]
LEFT JOIN "account" ON
"post"."author_id" = "account"."user_id" AND
"album"."user_id" = "account"."user_id"
Condições adicionais de JOIN
Você também pode adicionar condições lógicas à cláusula join.
"[>]comment" => [
	"author_id" => "user_id",
	"AND" => [
		"rate[>]" => 50
	]
]
LEFT JOIN "comment" ON "post"."author_id" = "comment"."user_id" AND "rate" > 50
JOIN com um objeto Raw
"[>]account" => Medoo::raw("ON <post.author_id> = <account.user_id>")
LEFT JOIN "account" ON "post"."author_id" = "account"."user_id"

Mapeamento de dados

Você pode personalizar a estrutura dos dados retornados. A chave de mapeamento não precisa corresponder ao nome da coluna original e há suporte para saída aninhada.
$data = $database->select("post", [
	"[>]account" => ["user_id"]
], [
	"post.content",

	"userData" => [
		"account.user_id",
		"account.email",

		"meta" => [
			"account.location",
			"account.gender"
		]
	]
], [
	"LIMIT" => [0, 2]
]);

echo json_encode($data);
[
	{
		"content": "Hello world!",
		"userData": {
			"user_id": "1",
			"email": "foo@example.com",
			"meta": {
				"location": "New York",
				"gender": "male"
			}
		}
	},
	{
		"content": "Hey everyone",
		"userData": {
			"user_id": "2",
			"email": "bar@example.com",
			"meta": {
				"location": "London",
				"gender": "female"
			}
		}
	}
]

Mapeamento de índice

Se você usar um nome de coluna como primeira chave na definição da coluna, o resultado será indexado por essa coluna.
$data = $database->select("post", [
	"user_id" => [
		"nickname",
		"location",
		"email"
	]
]);
{
	"10": {
		"nickname": "foo",
		"location": "New York",
		"email": "foo@example.com"
	},
	"12": {
		"nickname": "bar",
		"location": "New York",
		"email": "bar@medoo.in"
	}
}

Declaracoes de tipos de dados

Você pode declarar explicitamente o tipo de saída para campos selecionados.
// Tipos de dados suportados: [String | Bool | Int | Number | Object | JSON]
// [String] is the default type for all output values.
// [Object] represents PHP data serialized with serialize() and decoded with unserialize().
// [JSON] represents valid JSON data and will be decoded with json_decode().

$data = $database->select("post", [
	"[>]account" => ["user_id"]
], [
	"post.post_id",

	"profile" => [
		"account.age [Int]",
		"account.is_locked [Bool]",
		"account.userData [JSON]"
	]
]);

echo json_encode($data);
[
	{
		"post_id": "1",
		"profile": {
			"age": 20,
			"is_locked": true,
			"userData": ["foo", "bar", "tim"]
		}
	},
	{
		"post_id": "2",
		"profile": {
			"age": 25,
			"is_locked": false,
			"userData": ["mydata1", "mydata2"]
		}
	}
]
// Armazene um objeto no banco de dados e recupere-o depois.
class Foo {
	var $bar = "cat";

	public function __wakeup()
	{
		$this->bar = "dog";
	}
}

$object_data = new Foo();

$database->insert("account", [
	"data" => $object_data
]);

$data = $database->select("account", [
	"data [Object]"
]);

echo $data[0]["data"]->bar;

// O método __wakeup() do objeto é chamado durante o unserialize().
// Portanto, a saída é "dog".

Aliases

Você pode atribuir um alias a um nome de coluna ou tabela. Isto é especialmente útil em consultas unidas para evitar conflitos de nomes ou tornar a saída mais clara.
$data = $database->select("account", [
	"user_id",
	"nickname (my_nickname)"
]);

// Resultado de exemplo:
// array(
//  [0] => array(
//	  "user_id" => "1",
//	  "my_nickname" => "foo"
//  ),
//  [1] => array(
//	  "user_id" => "2",
//	  "my_nickname" => "bar"
//  )
// )

$data = $database->select("post (content)", [
	"[>]account (user)" => "user_id",
], [
	"content.user_id (author_id)",
	"user.user_id"
]);

// Resultado de exemplo:
// array(
//  [0] => array(
//	  "author_id" => "1",
//	  "user_id" => "321"
//  ),
//  [1] => array(
//	  "author_id" => "2",
//	  "user_id" => "322"
//  )
// )
SELECT
	"content"."user_id" AS "author_id",
	"user"."user_id"
FROM
	"post" AS "content"
LEFT JOIN "account" AS "user" USING ("user_id")

DISTINCT

Para adicionar a palavra-chave DISTINCT a uma coluna selecionada, prefixe o nome da coluna com @.
$data = $database->select("account", [
	// DISTINCT sera aplicado a esta coluna.
	"@location",
	
	"id",
	"name",
]);
SELECT DISTINCT "location", "id", "name"
FROM "account"
Para contar valores distintos, use uma expressão bruta.
$data = $database->select("account", [
	"unique_locations" => Medoo::raw("COUNT(DISTINCT <location>)")
]);
SELECT COUNT(DISTINCT "location") AS "unique_locations"
FROM "account"