在SQL中从一行数据中减去另一行数据

发布于 2024-07-21 04:45:50 字数 889 浏览 5 评论 0原文

我被一些 SQL 难住了,我有几行数据,我想从前一行中减去一行,并让它一直向下重复。

所以这是表格:

CREATE TABLE foo (
  id,
  length
)
INSERT INTO foo (id,length) VALUES(1,1090)
INSERT INTO foo (id,length) VALUES(2,888)
INSERT INTO foo (id,length) VALUES(3,545)
INSERT INTO foo (id,length) VALUES(4,434)
INSERT INTO foo (id,length) VALUES(5,45)

我希望结果显示称为差异的第三列,该列是从下面的一行中减去一行,最后一行从零中减去。

+------+------------------------+
| id   |length |  difference  |
+------+------------------------+
|    1 | 1090  |  202         |
|    2 |  888  |  343         |
|    3 |  545  |  111         |
|    4 |  434  |  389         |
|    5 |   45  |   45         |

我尝试过自连接,但我不确定如何限制结果而不是让它自行循环。 我不能依赖 id 值对于给定的结果集是连续的,所以我不使用该值。 我可以扩展架构以包含某种顺序值。

这就是我尝试过的:

SELECT id, f.length, f2.length, (f.length - f2.length) AS difference
FROM foo f, foo f2

谢谢您的帮助。

I've been stumped with some SQL where I've got several rows of data, and I want to subtract a row from the previous row and have it repeat all the way down.

So here is the table:

CREATE TABLE foo (
  id,
  length
)
INSERT INTO foo (id,length) VALUES(1,1090)
INSERT INTO foo (id,length) VALUES(2,888)
INSERT INTO foo (id,length) VALUES(3,545)
INSERT INTO foo (id,length) VALUES(4,434)
INSERT INTO foo (id,length) VALUES(5,45)

I want the results to show a third column called difference which is one row subtracting from the one below with the final row subtracting from zero.

+------+------------------------+
| id   |length |  difference  |
+------+------------------------+
|    1 | 1090  |  202         |
|    2 |  888  |  343         |
|    3 |  545  |  111         |
|    4 |  434  |  389         |
|    5 |   45  |   45         |

I've tried a self join but I'm not exactly sure how to limit the results instead of having it cycle through itself. I can't depend that the id value will be sequential for a given result set so I'm not using that value. I could extend the schema to include some kind of sequential value.

This is what I've tried:

SELECT id, f.length, f2.length, (f.length - f2.length) AS difference
FROM foo f, foo f2

Thank you for the assist.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

笑咖 2024-07-28 04:45:50

这可能对你有帮助(在某种程度上)。


select a.id, a.length, 
coalesce(a.length - 
    (select b.length from foo b where b.id = a.id + 1), a.length) as diff
from foo a

This might help you (somewhat).


select a.id, a.length, 
coalesce(a.length - 
    (select b.length from foo b where b.id = a.id + 1), a.length) as diff
from foo a

喵星人汪星人 2024-07-28 04:45:50

伊佩!!! 这可以解决问题:

SELECT  f.id, f.length, 
    (f.length - ISNULL(f2.length,0)) AS diff
FROM foo f
LEFT OUTER JOIN foo f2
ON  f2.id = (f.id +1)

请检查其他情况,它适用于您发布的值!
请注意,这是针对 SQL Server 2005

Yipee!!! this does the trick:

SELECT  f.id, f.length, 
    (f.length - ISNULL(f2.length,0)) AS diff
FROM foo f
LEFT OUTER JOIN foo f2
ON  f2.id = (f.id +1)

Please check for other cases also, it is working for the values you posted!
Note this is for SQL Server 2005

流绪微梦 2024-07-28 04:45:50

那么它们只是按从大到小的顺序排列吗?

SELECT f.id, f.length, (f.length - ISNULL(t.length, 0)) AS difference
FROM foo AS f
LEFT JOIN (
    SELECT f1.id
        ,MAX(f2.length) as length
    FROM foo AS f1
    INNER JOIN foo AS f2
        ON f1.length > f2.length
    GROUP BY f1.id
) AS t -- this is the triangle
    ON t.id = f.id

对于 MySQL,您可以使用 COALESCE(或 IFNULL)而不是 ISNULL

So they are just ordered largest to smallest?

SELECT f.id, f.length, (f.length - ISNULL(t.length, 0)) AS difference
FROM foo AS f
LEFT JOIN (
    SELECT f1.id
        ,MAX(f2.length) as length
    FROM foo AS f1
    INNER JOIN foo AS f2
        ON f1.length > f2.length
    GROUP BY f1.id
) AS t -- this is the triangle
    ON t.id = f.id

You can use COALESCE (or IFNULL) instead of ISNULL for MySQL.

浮生面具三千个 2024-07-28 04:45:50

像这样的事情怎么样:

SELECT T2.ID, T2.[Length], T2.[Length]-T1.[Length] AS 'Difference'
FROM Foo AS T1 RIGHT OUTER JOIN Foo AS T2 ON ( T1.ID = (T2.ID-1) )
ORDER BY T1.ID

What about something like this:

SELECT T2.ID, T2.[Length], T2.[Length]-T1.[Length] AS 'Difference'
FROM Foo AS T1 RIGHT OUTER JOIN Foo AS T2 ON ( T1.ID = (T2.ID-1) )
ORDER BY T1.ID
囍笑 2024-07-28 04:45:50
Select f1.id, f1.seqnum, f2.seqnum, f1.length, f2.length, f1.length-f2.length 

From (

Select Id, length, row_number(order by length) 'seqnum'
From
foo

) f1

Inner join (

Select 
Id, length, row_number(order by length) 'seqnum' from foo union select 0, 0, 0

) f2 

On f1.seqnum = f2.seqnum + 1

Order by f1.length desc
Select f1.id, f1.seqnum, f2.seqnum, f1.length, f2.length, f1.length-f2.length 

From (

Select Id, length, row_number(order by length) 'seqnum'
From
foo

) f1

Inner join (

Select 
Id, length, row_number(order by length) 'seqnum' from foo union select 0, 0, 0

) f2 

On f1.seqnum = f2.seqnum + 1

Order by f1.length desc
萌面超妹 2024-07-28 04:45:50

编辑:修复重新读取 Q(误解)

SELECT f.id, 
       f2.id, 
       f.length, 
       f2.length, 
       (f.length -f2.length) AS difference
FROM foo f, 
     foo f2 
where f2.id = f.id+1

id 不明确

时的问题编辑:注意:在 mysql 5.0 中测试

edit: fixed when re-read Q (misunderstood)

SELECT f.id, 
       f2.id, 
       f.length, 
       f2.length, 
       (f.length -f2.length) AS difference
FROM foo f, 
     foo f2 
where f2.id = f.id+1

id was ambiguous

edit: note: tested in mysql 5.0

﹉夏雨初晴づ 2024-07-28 04:45:50

我遇到了这个问题,看看你的解决方案很有趣。
我觉得很奇怪,这样一个平常生活中的问题在 SQL 中竟然如此复杂。
由于我只需要报告中的值,因此我选择了完全不同的解决方案。
我正在运行 Ruby on Rails 作为 sqlite3 数据库的前端,并在视图中进行减法,如下所示:

在您的 ruby​​ 控制器中,有一个对象变量 @foo 保存查询返回的行。

在看来,just do

<table border=1>
  <tr>
    <th>id</th>
    <th>length</th>
    <th>difference</th>
  </tr>

<% for i in [email protected] do %>
  <tr>
    <td><%=h @foo[i].id %></td>
    <td><%=h @foo[i].length %></td>
    <td><% if ([email protected]) then %>
        <%=  @foo[i].length %>
      <% else %>
        <%= @foo[i+1].length.to_i - @foo[i].length.to_i %>
      <% end %>
    </td>
  </tr>
<% end %>
</table>

似乎比SQL 解决方案更健壮。

I had this problem and it was interesting to look at your solutions.
I find it strange that such a normal-life problem is so complicated in SQL.
As I need the values in a report only, I chose a completely different solution.
I'm running Ruby on Rails as the front end of my sqlite3 database, and just did the subtraction in the view like this:

In your ruby controller, there is a object variable @foo that holds the rows returned by your query.

In the view, just do

<table border=1>
  <tr>
    <th>id</th>
    <th>length</th>
    <th>difference</th>
  </tr>

<% for i in [email protected] do %>
  <tr>
    <td><%=h @foo[i].id %></td>
    <td><%=h @foo[i].length %></td>
    <td><% if ([email protected]) then %>
        <%=  @foo[i].length %>
      <% else %>
        <%= @foo[i+1].length.to_i - @foo[i].length.to_i %>
      <% end %>
    </td>
  </tr>
<% end %>
</table>

Seems to be more robust than the SQL solutions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文