Without select() the builder asks for *. select() replaces the column list, addSelect() appends to it, and 'title as name' aliases a column, which the grammar splits and quotes; DB::table('products as p') aliases a table the same way. distinct() applies to the whole row, as in Projections and DISTINCT.
$q = DB::table('products')->select('sku', 'title as name')->addSelect('stock');
echo $q->where('stock', '>', 50)->toRawSql(), "\n", json_encode($q->first()), "\n";
echo DB::table('customers')->distinct()->orderBy('country')->pluck('country'), "\n";
echo DB::table('products')->where('stock', 0)->pluck('title', 'sku'), "\n";
echo DB::table('customers')->where('email', 'chen@example.com')->value('name'), "\n";Output
select `sku`, `title` as `name`, `stock` from `products` where `stock` > 50
{"sku":"AC-MUG-01","name":"Semicolon Coffee Mug","stock":60}
["BR","JP","MY","NG","SE","TR","US"]
{"BK-SQL-02":"Indexing Deep Dive"}
Chen WeiThe builder is mutable: the where() in the second line changed $q, so first() used it. pluck('title', 'sku') keys one column by another, ready for a <select> menu. first(), value() and find($id) add limit 1; sole() adds limit 2 and throws unless exactly one row matches. Name the columns you need, so a covering index (Covering Indexes) can answer alone.