生クエリで同じテーブルの列を比較する
同じテーブルの異なる列を比較することは、開発者がよく遭遇する一般的なシナリオです。同じテーブル内の2つの数値や2つの日付を比較する例などがあります。これに関する既存のGitHub Issueがあります。
バージョン4.3.0以降、同じテーブル内の列を比較するために生クエリを使用する必要はありません。<model>.fields
プロパティを使用して列を比較できます。
以下の情報は、Prisma ORMバージョン4.3.0以前との下位互換性のために保持されています。
回避策
同じテーブル内の2つの列の値を比較することは、生クエリを使用することで実現できます。
数値の比較
バージョン4.3.0以降、同じテーブル内の列を比較するために生クエリを使用する必要はありません。<model>.fields
プロパティを使用して列を比較できます。詳細はこちら
異なる列の値を比較する1つのユースケースとして、いいねよりもコメントが多い投稿を取得する場合があります。この場合、commentsCount
とlikesCount
の値を比較する必要があります。
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
likesCount Int
commentsCount Int
}
クエリ(使用するデータベースによって異なります)は次のようになります。
PostgreSQL / CockroachDB
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function initiateNumbersComparisonRawQuery() {
const response =
await prisma.$queryRaw`SELECT * FROM "public"."Post" WHERE "likesCount" < "commentsCount";`
console.log(response)
}
await initiateNumbersComparisonRawQuery()
MySQL
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function initiateNumbersComparisonRawQuery() {
const response =
await prisma.$queryRaw`SELECT * FROM \`public\`.\`Post\` WHERE \`likesCount\` < \`commentsCount\`;`
console.log(response)
}
await initiateNumbersComparisonRawQuery()
SQLite
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function initiateNumbersComparisonRawQuery() {
const response =
await prisma.$queryRaw`SELECT * FROM "Post" WHERE "likesCount" < "commentsCount";`
console.log(response)
}
await initiateNumbersComparisonRawQuery()
上記のクエリを実行すると(データベースによって異なります)、コメントと比較して「いいね」が少ない投稿がフィルタリングされます。
クエリ応答
;[
{
id: 1,
createdAt: '2022-03-03T12:08:11.421+00:00',
updatedAt: '2022-03-03T12:08:11.422+00:00',
title: 'Hello World',
content: 'This is my first post',
published: false,
authorId: 1,
likesCount: 50,
commentsCount: 100,
},
]
日付の比較
バージョン4.3.0以降、同じテーブル内の列を比較するために生クエリを使用する必要はありません。<model>.fields
プロパティを使用して列を比較できます。詳細はこちら
同様に、日付を比較する必要がある場合も、生クエリを使用して同じことを実現できます。
例えば、期日後に完了したすべてのプロジェクトを取得するユースケースが考えられます。
model Project {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id])
authorId Int
dueDate DateTime
completedDate DateTime
createdAt DateTime @default(now())
}
クエリ(使用するデータベースによって異なります)は次のようになります。
PostgreSQL / CockroachDB
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function initiateDatesComparisonRawQuery() {
const response =
await prisma.$queryRaw`SELECT * FROM "public"."Project" WHERE "completedDate" > "dueDate";`
console.log(response)
}
await initiateDatesComparisonRawQuery()
MySQL
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function initiateDatesComparisonRawQuery() {
const response =
await prisma.$queryRaw`SELECT * FROM \`public\`.\`Project\` WHERE \`completedDate\` > \`dueDate\`;`
console.log(response)
}
await initiateDatesComparisonRawQuery()
SQLite
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function initiateDatesComparisonRawQuery() {
const response =
await prisma.$queryRaw`SELECT * FROM "Project" WHERE "completedDate" > "dueDate";`
console.log(response)
}
await initiateDatesComparisonRawQuery()
上記のクエリを実行すると、completedDate
がdueDate
より後のプロジェクトが取得されます。
クエリ応答
;[
{
id: 1,
title: 'Project 1',
authorId: 1,
dueDate: '2022-03-10T00:00:00+00:00',
completedDate: '2022-03-12T00:00:00+00:00',
createdAt: '2022-03-03T12:08:11.421+00:00',
},
]