按自定义列仅获取子查询中每个行顺序的第一个结果

Get only first result in subquery for each row order by custom column

我的大脑无法解决一个简单的(我认为)SQL 问题,我需要你的帮助。我搜索了很多 Whosebug,但找不到适合我的案例的正确答案。

我有什么:

table : expense_budgets
编号
per_member
最大值
from_date
organization_id
organization_type_id
created_at
updated_at


CREATE TABLE IF NOT EXISTS `expense_budgets` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `per_member` double NOT NULL,
  `maximum` double NOT NULL,
  `from_date` date DEFAULT NULL,
  `organization_id` bigint(20) unsigned DEFAULT NULL,
  `organization_type_id` bigint(20) unsigned NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`)
)
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (1, 10, 10000, NULL, NULL, 2, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (2, 5, 5000, NULL, NULL, 3, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (3, 10, 40, NULL, NULL, 4, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (4, 5, 5000, NULL, NULL, 5, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (6, 15, 15000, '2020-09-25', NULL, 2, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (7, 15, 15000, '2020-09-29', NULL, 2, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (8, 15, 15000, '2020-09-26', NULL, 2, '2020-09-14 16:43:52', NULL);
INSERT INTO `expense_budgets` (`id`, `per_member`, `maximum`, `from_date`, `organization_id`, `organization_type_id`, `created_at`, `updated_at`) VALUES (9, 15, 15000, '2020-09-27', NULL, 2, '2020-09-14 16:43:52', NULL);

我想要的:我必须为给定日期的每个组织类型获取最接近的 expense_budget 记录。所以我应用重量自定义列来订购它们。如果我只有一个空 from_date 的记录,这意味着这是默认值,如果我有一个日期,我想要从现在开始最近的较低 from_date。

SELECT id, organization_type_id, case when from_date IS null then 1 when CURDATE() >= from_date THEN 3 ELSE 2 END AS weight
FROM expense_budgets
ORDER BY weight desc,from_date ASC;

但我找不到如何将其集成到子查询或连接中以获得结果(如果当前日期是 2020-09-28):

id;per_member;maximum;from_date;organization_id;organization_type_id;created_at;updated_at
2;5;5000;NULL;NULL;3;2020-09-14 16:43:52;NULL
3;10;40;NULL;NULL;4;2020-09-14 16:43:52;NULL
4;5;5000;NULL;NULL;5;2020-09-14 16:43:52;2020-09-28 09:46:24
9;15;15000;2020-09-27;NULL;2;2020-09-14 16:43:52;NULL

你明白了吗?每个 organization_type_id 只有一个记录,其中包含基于案例子查询的顺序选择的值。

预先感谢您的回答

您可以尝试通过添加以下格式的示例数据来编辑您的问题:

  • 输入包含 ```SQL 的行,即三个 back-ticks 后跟关键字 SQL。
  • 然后按照我在下面输入的格式输入您的数据(我忽略了 create/change 时间戳,因为它们似乎与问题无关)。我只是确定数据不具有代表性,因此您必须对其进行调整以反映您的挑战。
  • 以一行结束您的“引用代码”输入,仅包含:```
```SQL
WITH
expense_budgets(id,per_member,maximum,fromdt,orgid,org_tpid) AS (
          SELECT  1,15,15000,DATE '2020-09-12',NULL::INT,2
UNION ALL SELECT  2,20,15000,DATE '2020-09-13',NULL::INT,3
UNION ALL SELECT  3, 5,15000,DATE '2020-09-14',NULL::INT,4
UNION ALL SELECT  4,35,15000,DATE '2020-09-15',NULL::INT,2
UNION ALL SELECT  5, 5,15000,DATE '2020-09-16',NULL::INT,3
UNION ALL SELECT  6,15,15000,DATE '2020-09-17',NULL::INT,4
UNION ALL SELECT  7, 2,15000,DATE '2020-09-18',NULL::INT,2
UNION ALL SELECT  8, 7,15000,DATE '2020-09-19',NULL::INT,3
UNION ALL SELECT  9, 6,15000,DATE '2020-09-20',NULL::INT,4
UNION ALL SELECT 10, 5,15000,DATE '2020-09-21',NULL::INT,2
UNION ALL SELECT 11,35,15000,DATE '2020-09-22',NULL::INT,3
UNION ALL SELECT 12,15,15000,DATE '2020-09-23',NULL::INT,4
)
SELECT * FROM expense_budgets ; -- < replace with real query, please ...
-- ``` un-comment this , (three back-ticks don't display in quoted code ...

假设组合 organization_type_id + from_date 是唯一的:

with lastbudgets as (select eb2.organization_type_id, max(eb2.from_date) as from_date
                       from expense_budgets eb2
                      where eb2.from_date is null or eb2.from_date <= now()
                      group by eb2.organization_type_id)
select eb.* 
  from expense_budgets eb 
     inner join lastbudgets lb 
             on lb.organization_type_id = eb.organization_type_id
            and ((lb.from_date is null and eb.from_date is null) or lb.from_date = eb.from_date)

更新:空大小写的额外逻辑