如果我有一个包含以下架构的表:
CREATE TABLE diet_watch (
entry_date date NOT NULL,
weight double precision NOT NULL
);
INSERT INTO diet_watch VALUES ('2001-01-01', 128.2);
INSERT INTO diet_watch VALUES ('2001-01-02', 121.0);
INSERT INTO diet_watch VALUES ('2001-01-03', 122.3);
INSERT INTO diet_watch VALUES ('2001-01-04', 303.7);
INSERT INTO diet_watch VALUES ('2001-01-05', 121.0);
INSERT INTO diet_watch VALUES ('2001-01-06', 128.0);
我如何编写一个查询,以便在两个日期之间返回 FIRST 最小权重 AND 最小权重发生的日期?
理想情况下,这将是ANSI-SQL,即db不可知。如果我不得不被迫选择SQL风格,它将是PostgreSQL,因为那是我正在使用的数据库。
PSEUDO SQL:
SELECT min(entry_date), min(weight)
FROM diet_watch
where entry date between date1 and date2
group by entry_date;
答案 0 :(得分:3)
SELECT weight, entry_date
FROM diet_watch
WHERE entry_date BETWEEN '2001-01-02' AND '2001-01-06'
ORDER BY 1, 2
LIMIT 1;
适用于PostgreSQL或MySQL以及其他可能(不在Oracle或MS SQL Server中)。
SELECT weight, entry_date
FROM (
SELECT weight, entry_date
,row_number() OVER (ORDER BY weight, entry_date) AS rn
FROM diet_watch
WHERE entry_date between '2001-01-02' and '2001-01-06'
) AS x
WHERE rn = 1;
不支持未实现窗口功能的RDBMS(如MySQL)。
SELECT weight, entry_date
FROM diet_watch
WHERE entry_date BETWEEN '2001-01-02' AND '2001-01-06'
ORDER BY weight, entry_date
FETCH FIRST 1 ROWS ONLY;
只有少数RDBMS支持 - 找到list on Wikipedia。
支持所有这些的唯一 RDBMS是PostgreSQL(v8.4或更高版本)。
在评论中提问,我引用the manual here about ORDER BY:
每个表达式可以是输出列的名称或序号 (SELECT列表项),或者它可以是由...形成的任意表达式 输入列值。
强调我的。它只是一个语法快捷方式,由许多RDBMS支持。 SQL Server显然不在其中。
答案 1 :(得分:2)
SELECT min(entry_date), min(weight) from diet_watch where weight = (
SELECT MIN(weight) as wt from diet_watch where entry_date between date1 and date2
) and entry_date between date1 and date2
[编辑:答案略有调整,因为看起来问题已从找到最小日期的重量更改为最小重量日期]
此外,该问题要求“FIRST”最小重量......我假设这意味着最小重量的最早日期。
答案 2 :(得分:0)
您可以请求SELECT * ORDER BY权重ASC LIMIT 1(大多数DB支持LIMIT),或者根本不使用LIMIT,只检索光标的第一行。
否则,您需要JOIN才能获得最小值,然后检索最小值确实发生的日期;如果达到最低限度的多个日期,您仍然需要LIMIT和/或单次获取。
答案 3 :(得分:0)
根据Gerrat的回答,可以通过entry_date命令并抓住第一行。
SELECT top 1 entry_date, weight
FROM diet_watch
WHERE weight = (SELECT MIN(weight) as wt from diet_watch)
ORDER BY entry_date
编辑:这是SQL Server代码。但是你可以使用postgre中的等价物。