按自定义列仅获取子查询中每个行顺序的第一个结果
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)
更新:空大小写的额外逻辑
我的大脑无法解决一个简单的(我认为)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)
更新:空大小写的额外逻辑