# Selecting fields (/docs/framework/guides/selecting)



<SalesforceReference title="SELECT fields and FIELDS()" href="https://developer.salesforce.com/docs/platform/salesforce-soql-sosl/guide/sforce-api-calls-soql-select-fields.html" />

## Select the fields you need [#select-the-fields-you-need]

Start with an object API name, then select one field or a list:

```ts
import { db } from "./db";

const query = db
  .selectFrom("Account")
  .select("Id")
  .select(["Name", "AnnualRevenue"])
  .limit(25);

const accounts = await query.execute();

for (const account of accounts) {
  console.log(account.Id, account.Name, account.AnnualRevenue);
}
```

Selections accumulate. Object and field names come from your generated schema, so use Salesforce API names such as `AnnualRevenue` rather than display labels.

Kysoql does not expose `SELECT *`. Explicit fields keep payloads predictable and avoid picking up newly added org fields by accident.

## Rename result properties with aliases [#rename-result-properties-with-aliases]

Use `"field as alias"` when you want a different JavaScript property name:

```ts
import { db } from "./db";

const query = db
  .selectFrom("Account")
  .select(["Id as id", "Name as name", "Owner.Name as ownerName"]);

console.log(query.compile().soql);
// SELECT Id, Name, Owner.Name FROM Account

const accounts = await query.execute();

for (const account of accounts) {
  console.log(account.id, account.name, account.ownerName);
}
```

Salesforce does not support ordinary field aliases in record queries. Kysoql requests the real fields and reshapes the returned JavaScript rows for you.

An aliased relationship path becomes a flat property such as `ownerName`. An unaliased parent path keeps its nested relationship shape.

Grouped queries use Salesforce's native aliases for aggregate and grouped results.

## Use `FIELDS()` when you really want expansion [#use-fields-when-you-really-want-expansion]

`selectFields("standard" | "custom" | "all")` emits Salesforce's `FIELDS(...)` function and expands the inferred result from your generated metadata:

```ts
import { db } from "./db";

const query = db.selectFrom("Account").selectFields("all").limit(100);

console.log(query.compile().soql);
// SELECT FIELDS(ALL) FROM Account LIMIT 100
```

`FIELDS(CUSTOM)` and `FIELDS(ALL)` can return many fields. Salesforce requires them to be bounded. Kysoql therefore requires either a literal `LIMIT` of at most 200 or a direct `Id` filter that proves the query can return no more than 200 IDs.

```ts
import { db } from "./db";

const ids = ["001000000000001AAA", "001000000000002AAA"];

const query = db
  .selectFrom("Account")
  .selectFields("all")
  .where("Id", "in", ids);
```

The IDs above are placeholders. Use real Salesforce IDs when you execute the query.

Do not combine a selector with direct fields it already includes. For example, `select("Id").selectFields("all")` would select `Id` twice.

### Filtered codegen schemas [#filtered-codegen-schemas]

An object generated with a [field rule](/docs/codegen/field-filtering) is a partial schema. Typed `FIELDS()` selectors are disabled for that object, including inside child subqueries.

That restriction matters because Salesforce expands `FIELDS(...)` on the server, not from the TypeScript declarations on your machine. Use explicit `.select(...)` calls for filtered objects.

### Apex [#apex]

Apex supports `selectFields("standard")`. `"custom"` and `"all"` are rejected when a query switches to the Apex builder.

## What comes back? [#what-comes-back]

| Selection                | Inferred result                                                                         |
| ------------------------ | --------------------------------------------------------------------------------------- |
| Direct field             | The generated field type, including `null` where Salesforce metadata allows it.         |
| Field alias              | A flat property named by the alias.                                                     |
| Date, datetime, or time  | `string` rather than JavaScript `Date`.                                                 |
| Location                 | `{ latitude: number, longitude: number }` with applicable nullability.                  |
| Parent relationship path | A nested related object with applicable relationship nullability.                       |
| Child subquery           | `SalesforceQueryResult<Row>`. Native REST completes selected child pages automatically. |
| Function alias           | A property named by `.as(...)`.                                                         |

Salesforce may also include transport metadata such as `attributes`. Ordinary field selections do not add every possible transport property to the inferred row type. `TYPEOF` is the main exception because its discriminated union uses `attributes.type`.

## Replace an existing selection [#replace-an-existing-selection]

```ts
import { db } from "./db";

const base = db.selectFrom("Account").select(["Id", "Name"]);
const idsOnly = base.clearSelect().select("Id");
```

`clearSelect()` starts a fresh selection set without removing filters or ordering from the earlier builder.

Continue with [filtering](/docs/framework/guides/filtering), [relationships](/docs/framework/guides/relationships), or [SELECT functions](/docs/framework/guides/select-functions).
