这是一个简单的我的表
+-----------+----------------+-----------+
| id | date | meter |
------------+----------------+-----------+
| 1 | 2103-11-01 | 5 |
| 2 | 2103-11-10 | 8 |
| 4 | 2103-11-14 | 10 |
| 6 | 2103-11-20 | 18 |
| 7 | 2103-11-25 | 25 |
| 10 | 2103-11-29 | 30 |
+-----------+----------------+-----------+
如何在两个记录时间范围之间得到米的使用结果, 像贝娄一样
+----------------+----------------+-------+-----+--------+
| date1 | date2 | start | end | amount |
+----------------+----------------+-------+-----+--------+
| 2013-11-01 | 2013-11-10 | 5 | 8 | 3 |
| 2013-11-10 | 2013-11-14 | 8 | 10 | 2 |
| 2013-11-14 | 2013-11-20 | 10 | 18 | 8 |
| 2013-11-20 | 2013-11-25 | 18 | 25 | 7 |
| 2013-11-25 | 2013-11-29 | 25 | 30 | 5 |
+----------------+----------------+-------+-----+--------+
答案 0 :(得分:1)
编辑: 我明白了:
select meters1.date as date1, min(meters2.date) as date2, meters1.meter as start,
meters2.meter as end, (meters2.meter - meters1.meter) as amount
from meters meters1, meters meters2 where meters1.date < meters2.date
group by date1;
输出:
+------------+------------+-------+-----+--------+
| date1 | date2 | start | end | amount |
+------------+------------+-------+-----+--------+
| 2013-11-01 | 2013-11-10 | 5 | 8 | 3 |
| 2013-11-10 | 2013-11-14 | 8 | 10 | 2 |
| 2013-11-14 | 2013-11-20 | 10 | 18 | 8 |
| 2013-11-20 | 2013-11-25 | 18 | 25 | 7 |
| 2013-11-25 | 2013-11-29 | 25 | 30 | 5 |
+------------+------------+-------+-----+--------+
原帖:
这就是大部分时间:
select meters1.date as date1, meters2.date as date2, meters1.meter as start,
meters2.meter as end, (meters2.meter - meters1.meter) as amount
from meters meters1, meters meters2 having date1 < date2 order by date1;
输出:
+------------+------------+-------+-----+--------+
| date1 | date2 | start | end | amount |
+------------+------------+-------+-----+--------+
| 2013-11-01 | 2013-11-10 | 5 | 8 | 3 |
| 2013-11-01 | 2013-11-20 | 5 | 18 | 13 |
| 2013-11-01 | 2013-11-29 | 5 | 30 | 25 |
| 2013-11-01 | 2013-11-14 | 5 | 10 | 5 |
| 2013-11-01 | 2013-11-25 | 5 | 25 | 20 |
| 2013-11-10 | 2013-11-20 | 8 | 18 | 10 |
| 2013-11-10 | 2013-11-29 | 8 | 30 | 22 |
| 2013-11-10 | 2013-11-14 | 8 | 10 | 2 |
| 2013-11-10 | 2013-11-25 | 8 | 25 | 17 |
| 2013-11-14 | 2013-11-25 | 10 | 25 | 15 |
| 2013-11-14 | 2013-11-20 | 10 | 18 | 8 |
| 2013-11-14 | 2013-11-29 | 10 | 30 | 20 |
| 2013-11-20 | 2013-11-25 | 18 | 25 | 7 |
| 2013-11-20 | 2013-11-29 | 18 | 30 | 12 |
| 2013-11-25 | 2013-11-29 | 25 | 30 | 5 |
+------------+------------+-------+-----+--------+
答案 1 :(得分:1)
如果它的SQL服务器以这种方式尝试
WITH cte AS
(
SELECT *, ROW_NUMBER() OVER (ORDER BY date) rnum
FROM table1
)
SELECT c.date date1, p.date date2, c.meter [start], p.meter [end], p.meter - c.meter amount
FROM cte c JOIN cte p
ON c.rnum = p.rnum - 1
这是 SQLFiddle 演示
如果是MySQL,那么你可以做
SELECT date1, date2, meter1, meter2, meter2 - meter1 amount
FROM
(
SELECT @d date2, date date1, @m meter2, meter meter1, @d := date, @m := meter
FROM table1 CROSS JOIN (SELECT @d := NULL, @m := NULL) i
ORDER BY date DESC
) q
WHERE date2 IS NOT NULL
ORDER BY date1
这是 SQLFiddle 演示
两种情况下的输出:
| DATE1 | DATE2 | START | END | AMOUNT | |------------|------------|-------|-----|--------| | 2103-11-01 | 2103-11-10 | 5 | 8 | 3 | | 2103-11-10 | 2103-11-14 | 8 | 10 | 2 | | 2103-11-14 | 2103-11-20 | 10 | 18 | 8 | | 2103-11-20 | 2103-11-25 | 18 | 25 | 7 | | 2103-11-25 | 2103-11-29 | 25 | 30 | 5 |
答案 2 :(得分:1)
的MySQL
SELECT DATES.date1,
DATES.date2,
m1.meter as start,
m2.meter as end,
m2.meter - m1.meter as amount
FROM
(SELECT date as date1,
(SELECT min(date)
FROM tableName t2
WHERE t2.date > t1.date) as date2
FROM tableName t1
)DATES,
tableName m1,
tableName m2
WHERE DATES.date2 IS NOT NULL
AND m1.date = DATES.date1
AND m2.date = DATES.date2
ORDER BY DATES.date1
MS-SQL SERVER 2002中的将单词end
更改为"end"
,因为它抱怨end
附近的语法
答案 3 :(得分:0)
如果你正在使用MySQL,那么自联接在这里会很好用。使用ON
子句将表连接到自身,以确保不将相同的记录连接到自身。这将为您提供数据的((N * N) - N)
个排列,其中N
是原始行的数量。
SELECT
...
FROM
tableName first
JOIN
tableName second
ON first.id != second.id
然后,所有关于SELECT
正确的东西(包括计算两个meter
值之间的差异)。要获取您发布的结果集中的列,您可能需要SELECT
:
first.date AS date1,
second.date AS date2,
first.meter AS start,
second.meter AS end,
ABS(first.meter - second.meter) AS amount
修改的 啊,我明白了。我设想过你曾经在路线图上看到的城际里程图(你在行和列中有相同的城市,交叉点中的单元格表示这两者之间的里程数)城市。
但看起来您只想比较一个日期与下一个日期的值。如果是这种情况,你可以利用MySQL处理GROUP
和ORDER
的方式...但要小心,因为我不确定这是否有保证:
mysql> SELECT
table1.date AS date1,
table2.date AS date2,
table1.meter AS start,
table2.meter AS end,
ABS(table1.meter - table2.meter) AS amount
FROM tableName table1
JOIN tableName table2
WHERE table2.date > table1.date
GROUP BY table1.date
ORDER BY table2.date - table1.date;
+---------------------+---------------------+-------+------+--------+
| date1 | date2 | start | end | amount |
+---------------------+---------------------+-------+------+--------+
| 2103-11-25 00:00:00 | 2103-11-29 00:00:00 | 25 | 30 | 5 |
| 2103-11-10 00:00:00 | 2103-11-14 00:00:00 | 8 | 10 | 2 |
| 2103-11-20 00:00:00 | 2103-11-25 00:00:00 | 18 | 25 | 7 |
| 2103-11-14 00:00:00 | 2103-11-20 00:00:00 | 10 | 18 | 8 |
| 2103-11-01 00:00:00 | 2103-11-10 00:00:00 | 5 | 8 | 3 |
+---------------------+---------------------+-------+------+--------+
5 rows in set (0.00 sec)
答案 4 :(得分:0)
您还没有说清楚您是否真的使用mySQL或SQL Server,但我发布的解决方案适用于SQL 2008及更高版本。可能会在2005年工作,但我无法测试。
-- Set up a temp table with sample data
DECLARE @testData AS TABLE(
id int,
dt date,
meter int)
INSERT @testData(id, dt, meter) VALUES
(1, '2013-11-01', 5)
,(2, '2013-11-10', 8)
,(4, '2013-11-14', 10)
,(6, '2013-11-20', 18)
,(7, '2013-11-25', 25)
,(10, '2013-11-29',30)
---------------------------------------------
-- Begin SQL Server solution
;WITH cte AS (
SELECT
ROW_NUMBER() OVER (ORDER BY id) AS rownum
,id
,dt
,meter
FROM
@testData AS [date2]
)
SELECT
t1.id
,t1.dt AS [date1]
,t2.dt AS [date2]
,t1.meter AS [start]
,t2.meter AS [end]
,t2.meter - t1.meter AS [amount]
FROM
cte t1
LEFT OUTER JOIN cte t2 ON (t2.rownum = t1.rownum + 1)
WHERE
t2.dt IS NOT NULL