gpt4 book ai didi

sql - 获取所有记录 matchung 某些条件或通过添加其他条件至少 10

转载 作者:行者123 更新时间:2023-11-29 14:06:48 24 4
gpt4 key购买 nike

有什么方法可以获取所有符合这些条件的记录:

  • ( userid = 1 AND (status < 2 OR time > INTERVAL '1 day') )

如果记录少于 10 条或更多(如果有):

  • userid = 1

最多 10 个(最后,按 time )?

最佳答案

您想获取所有匹配的记录。硬 LIMIT 10 将是错误的。您只想根据次要条件添加最多 10 行如果没有足够的行供您的主要 条件。但是,仅主要条件就可能已经超过 10 行。

PL/pgSQL解决方案

我能想到的最快方法是 plpgsql 函数:

CREATE OR REPLACE FUNCTION f_tbl_top(_uid int = 1, _min int = 10)
RETURNS SETOF tbl AS
$func$
DECLARE
_ct int;
BEGIN

RETURN QUERY
SELECT *
FROM tbl
WHERE userid = _uid
AND (status < 2 OR time > interval '1 day')
ORDER BY time DESC;

GET DIAGNOSTICS _ct = ROW_COUNT;
_ct := _min - _ct; -- calculate diff

IF _ct > 0 THEN
RETURN QUERY
SELECT *
FROM tbl
WHERE userid = _uid
AND (status < 2 OR time > interval '1 day') IS NOT TRUE
ORDER BY time DESC
LIMIT _ct;
END IF;

END
$func$ LANGUAGE plpgsql;

调用:

SELECT * FROM f_tbl_top();

我添加了两个参数:user_id (_uid) 和最小行数 (_min)。它们分别默认为 1/10。因此,当您在不提供参数的情况下调用该函数时,如果有足够的 userid = 1,您至少会得到 10 行。或者,对用户 7 和至少 9 行执行相同操作:

SELECT * FROM f_tbl_top(7, 9);

或者:

SELECT * FROM f_tbl_top(_uid := 7, _min := 9);

如果您的 time 列可以为 NULL,也要小心。那么你需要:

ORDER  BY time DESC NULLS LAST

但不要使用像 time 这样的基本类型名称作为列名开头,更不用说 interval,这是相当误导的。

第二个 SELECT 的条件可能会根据您的实际表定义进行优化。

纯SQL

如果您更喜欢纯 SQL 解决方案,您可以使用 CTE :

WITH cte AS (
SELECT *
FROM tbl
WHERE userid = 1
AND (status < 2 OR time > interval '1 day')
ORDER BY time DESC
)
TABLE cte
UNION ALL
( -- parentheses required!
SELECT *
FROM tbl
WHERE userid = 1
AND (status < 2 OR time > interval '1 day') IS NOT TRUE
ORDER BY time DESC
LIMIT GREATEST((SELECT 10 - count(*) FROM cte), 0)
);

GREATEST(...)第二个 LIMIT 中的表达式避免了 LIMIT 子句中的非法负数。

关于sql - 获取所有记录 matchung 某些条件或通过添加其他条件至少 10,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32511462/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com