我有一个看起来像这样的表:
+--------------------+---------+
| Month (date) | amount |
+--------------------+---------+
| 2016-10-01 | 20 |
| 2016-08-01 | 10 |
| 2016-07-01 | 17 |
+--------------------+---------+
我正在寻找满足以下条件的查询(sql语句):
在示例表中,我正在寻找的行是:
+--------------------+---------+
| 2016-08-01 | 10 |
+--------------------+---------+
有没有人想过非复杂的选择查询?
提前致谢, 彼得
答案 0 :(得分:4)
您可能需要以下内容:
SELECT *
FROM ( SELECT *
FROM test
WHERE TRUNC(SYSDATE, 'month') >= month
ORDER BY CASE
WHEN TRUNC(SYSDATE, 'month') = month
THEN 0 /* if current month, ordered last */
ELSE 1 /* previous months are ordered first */
END DESC,
month DESC /* among previous months, the greatest first */
)
WHERE ROWNUM = 1
答案 1 :(得分:1)
我会使用row_number()
:
select t.*
from (select t.*,
row_number() over (order by (case when to_char(dte, 'YYYY-MM') = to_char(sysdate, 'YYYY-MM') then 1 else 2 end) desc,
dte desc
) as seqnum
from t
) t
where seqnum = 1;
实际上,您不需要row_number()
:
select t.*
from (select t.*
from t
order by (case when to_char(dte, 'YYYY-MM') = to_char(sysdate, 'YYYY-MM') then 1 else 2 end) desc,
dte desc
) t
where rownum = 1;
答案 2 :(得分:1)
使用MAX的另一种方式
WITH tbl AS (
SELECT TO_DATE('2016-10-01', 'YYYY-MM-DD') AS "month", 20 AS amount FROM dual
UNION
SELECT TO_DATE('2016-08-01', 'YYYY-MM-DD') AS "month", 10 AS amount FROM dual
UNION
SELECT TO_DATE('2016-07-01', 'YYYY-MM-DD') AS "month", 5 AS amount FROM dual
)
SELECT *
FROM tbl
WHERE TRUNC("month", 'MONTH') = NVL((SELECT MAX(t."month")
FROM tbl t
WHERE t."month" < TRUNC(SYSDATE, 'MONTH')),
TRUNC(SYSDATE, 'MONTH'));
答案 3 :(得分:0)
这不是最好的查询,但应该有效。
select amount, date from (
select amount, date, row_number over(partition by HERE_PUT_ID order by
case trunc(date, 'month') when trunc(sysdate, 'month') then to_date('00010101', 'yyyymmdd') else trunc(date, 'month') end
desc) r)
where r = 1;
我猜你在表中有一些id,所以如果你想要查询整个表只是删除id列而不是HERE_PUT_ID:partition by HERE_PUT_ID
答案 4 :(得分:0)
我添加了更多用于测试的数据,以及一个&#34; id&#34;列(更现实的场景),以显示这将如何工作。如果没有&#34; id&#34;在您的数据中,只需从解决方案中删除对它的任何引用。
备注 - month
是保留的Oracle字词,不要将其用作列名。该解决方案假定日期列包含已截断到月初的日期。 &#34;中的诀窍&#34;在dense_rank last
中,当月份是当前月份时,指定一个值(任意值!);默认情况下,分配给所有其他月份的值为NULL,默认情况下以升序排列任何非空值。
如果执行时间很重要,您可能希望测试各种解决方案的效率。
with
inputs ( id, mth, amount ) as (
select 1, date '2016-10-01', 20 from dual union all
select 1, date '2016-08-01', 10 from dual union all
select 1, date '2016-07-01', 17 from dual union all
select 2, date '2016-10-01', 30 from dual union all
select 2, date '2016-09-01', 25 from dual union all
select 3, date '2016-10-01', 20 from dual union all
select 4, date '2016-08-01', 45 from dual union all
select 4, date '2016-06-01', 30 from dual
)
-- end of TEST DATA - the solution (SQL query) is below this line
select id,
max(mth) keep(dense_rank last order by
case when mth = trunc(sysdate, 'mm') then 0 end, mth) as mth,
max(amount) keep(dense_rank last order by
case when mth = trunc(sysdate, 'mm') then 0 end, mth) as amount
from inputs
group by id
order by id -- ORDER BY is optional
;
ID MTH AMOUNT
--- ---------- -------
1 2016-08-01 10
2 2016-09-01 25
3 2016-10-01 20
4 2016-08-01 45
答案 5 :(得分:0)
您可以按照您想要的方向对数据进行排序:
tr min; %b;
te min; %b;