본문으로 건너뛰기

고유하게 선택하기

프리즈마 클라이언트를 사용하면 프리즈마 질의 응답에서 findMany 질의에 distinct를 사용하여 중복된 행을 필터링할 수 있습니다. distinct는 종종 테이블의 행에서 특정 고유한 값 조합을 식별하기 위해 select와 함께 사용됩니다.

다음 예시에서는 고유한 name 필드 값이 있는 모든 User 레코드의 모든 필드를 반환합니다.

ts
const result = await prisma.user.findMany({
where: {},
distinct: ['name'],
})
ts
const result = await prisma.user.findMany({
where: {},
distinct: ['name'],
})

다음 예시는 고유한 role 필드 값(예 : ADMINUSER)을 반환합니다.

ts
const distinctRoles = await prisma.user.findMany({
distinct: ['role'],
select: {
role: true,
},
})
ts
const distinctRoles = await prisma.user.findMany({
distinct: ['role'],
select: {
role: true,
},
})
결과
ts
[
{
role: 'USER',
},
{
role: 'ADMIN',
},
]
결과
ts
[
{
role: 'USER',
},
{
role: 'ADMIN',
},
]

distinct의 구현 방식

프리즈마의 distinct 옵션은 SELECT DISTINCT SQL을 사용하지 않습니다. 대신 다음을 사용합니다.

  • SELECT 질의
  • 고유한 선택을 위한 인메모리 후처리

distinct 질의에서 selectinclude를 지원하기 위해 이러한 방식으로 설계되었습니다.

다음 예시에서는 각 플레이어의 게임당 최고 점수를 반환하기 위해, score로 정렬된 고유한 gameIdplayerId를 선택합니다. 질의는 includeselect를 사용하여 추가 데이터를 포함합니다.

  • score를 선택함 (Play 필드에서)
  • 관련 선수 이름을 선택함 (PlayUser의 관계에서)
  • 관련 게임 이름을 선택함 ( PlayGame의 관계에서)
예시 스키마
prisma
model User {
id Int @id @default(autoincrement())
name String?
play Play[]
}
model Game {
id Int @id @default(autoincrement())
name String?
play Play[]
}
model Play {
id Int @id @default(autoincrement())
score Int? @default(0)
playerId Int?
player User? @relation(fields: [playerId], references: [id])
gameId Int?
game Game? @relation(fields: [gameId], references: [id])
}
예시 스키마
prisma
model User {
id Int @id @default(autoincrement())
name String?
play Play[]
}
model Game {
id Int @id @default(autoincrement())
name String?
play Play[]
}
model Play {
id Int @id @default(autoincrement())
score Int? @default(0)
playerId Int?
player User? @relation(fields: [playerId], references: [id])
gameId Int?
game Game? @relation(fields: [gameId], references: [id])
}
질의
ts
const distinctScores = await prisma.play.findMany({
distinct: ['playerId', 'gameId'],
orderBy: {
score: 'desc',
},
select: {
score: true,
game: {
select: {
name: true,
},
},
player: {
select: {
name: true,
},
},
},
})
질의
ts
const distinctScores = await prisma.play.findMany({
distinct: ['playerId', 'gameId'],
orderBy: {
score: 'desc',
},
select: {
score: true,
game: {
select: {
name: true,
},
},
player: {
select: {
name: true,
},
},
},
})
결과
ts
[
{
score: 900,
game: { name: 'Pacman' },
player: { name: 'Bert Bobberton' }
},
{
score: 400,
game: { name: 'Pacman' },
player: { name: 'Nellie Bobberton' }
}
]
결과
ts
[
{
score: 900,
game: { name: 'Pacman' },
player: { name: 'Bert Bobberton' }
},
{
score: 400,
game: { name: 'Pacman' },
player: { name: 'Nellie Bobberton' }
}
]

selectdistinct가 없는 질의는 다음을 반환합니다.

ts
[
{
gameId: 2,
playerId: 5
},
{
gameId: 2,
playerId: 10
}
]
ts
[
{
gameId: 2,
playerId: 5
},
{
gameId: 2,
playerId: 10
}
]