在查询中有条件地过滤行以进一步过滤 postgres 中的查询结果
Filtering rows conditionally within a query to further filter the query result in postgres
我主要使用 NoSql 数据库,但很长一段时间后我正在尝试 SQL。我有一张 table 命名发票。
id
invoice_type
valid_until
01
quote
2023-03-10
02
quote
2021-03-10
03
reservation
2022-03-11
我正在尝试根据名为 type
的查询参数过滤行
- 如果
type = reservation
,Return所有行invoice_type = reservation
- 如果
type = quote
,Return所有行invoice_type = quote AND valid_until > now()
- 如果
type = undefined || invalid
,两种类型的 Return 行,但对于具有 invoice_type = quote
的行,仍会根据 valid_until
字段过滤掉它们。
我正在为第 3 条规则而苦苦挣扎,我的想法是获取所有行,然后仅在具有 type = quote
的行上应用 valid_until
的过滤器
预期输出
GET api/invoices?type=quote
{ id: 01, invoice_type: 'quote', valid_until: '2023-03-10' }
GET api/invoices?type=reservation
{ id: 03, invoice_type: 'reservation', valid_until: '2022-03-11' }
GET api/invoices
[
{ id: 01, invoice_type: 'quote', valid_until: '2023-03-10' },
{ id: 03, invoice_type: 'reservation', valid_until: '2022-03-11' }
]
目前的解决方案是
const invoices = await knex('invoices').where((builder) => {
switch (type) {
case 'quote':
builder.where({ type }).where('valid_until', '>', 'now()');
break;
case 'reservation':
builder.where({ type });
break;
default:
console.log(type);
builder
.where({ type: 'quote' })
.where('valid_until', '>', 'now()')
.orWhere({ type: 'reservation' });
break;
}
});
它正在工作,但我希望完全通过 SQL 来实现它。
参数化查询中的where
子句可以完成这一切。这里是。 :type
是参数。
select * from invoices
where
(:type = 'reservation' AND invoice_type = 'reservation')
OR (:type = 'quote' AND invoice_type = 'quote' AND valid_until > now())
OR (:type in ('undefined', 'invalid') AND case
when invoice_type = 'quote' then valid_until > now()
else true
end
);
我主要使用 NoSql 数据库,但很长一段时间后我正在尝试 SQL。我有一张 table 命名发票。
id | invoice_type | valid_until |
---|---|---|
01 | quote | 2023-03-10 |
02 | quote | 2021-03-10 |
03 | reservation | 2022-03-11 |
我正在尝试根据名为 type
- 如果
type = reservation
,Return所有行invoice_type = reservation
- 如果
type = quote
,Return所有行invoice_type = quote AND valid_until > now()
- 如果
type = undefined || invalid
,两种类型的 Return 行,但对于具有invoice_type = quote
的行,仍会根据valid_until
字段过滤掉它们。
我正在为第 3 条规则而苦苦挣扎,我的想法是获取所有行,然后仅在具有 type = quote
valid_until
的过滤器
预期输出
GET api/invoices?type=quote
{ id: 01, invoice_type: 'quote', valid_until: '2023-03-10' }
GET api/invoices?type=reservation
{ id: 03, invoice_type: 'reservation', valid_until: '2022-03-11' }
GET api/invoices
[
{ id: 01, invoice_type: 'quote', valid_until: '2023-03-10' },
{ id: 03, invoice_type: 'reservation', valid_until: '2022-03-11' }
]
目前的解决方案是
const invoices = await knex('invoices').where((builder) => {
switch (type) {
case 'quote':
builder.where({ type }).where('valid_until', '>', 'now()');
break;
case 'reservation':
builder.where({ type });
break;
default:
console.log(type);
builder
.where({ type: 'quote' })
.where('valid_until', '>', 'now()')
.orWhere({ type: 'reservation' });
break;
}
});
它正在工作,但我希望完全通过 SQL 来实现它。
参数化查询中的where
子句可以完成这一切。这里是。 :type
是参数。
select * from invoices
where
(:type = 'reservation' AND invoice_type = 'reservation')
OR (:type = 'quote' AND invoice_type = 'quote' AND valid_until > now())
OR (:type in ('undefined', 'invalid') AND case
when invoice_type = 'quote' then valid_until > now()
else true
end
);