Subtracting one row of data from another in SQL

前端 未结 7 740
抹茶落季
抹茶落季 2020-12-09 19:06

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 her

相关标签:
7条回答
  • 2020-12-09 19:30

    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

    0 讨论(0)
  • 2020-12-09 19:30

    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
    
    0 讨论(0)
  • 2020-12-09 19:33

    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.

    0 讨论(0)
  • 2020-12-09 19:36
    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
    
    0 讨论(0)
  • 2020-12-09 19:37

    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

    0 讨论(0)
  • 2020-12-09 19:39

    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 0..@foo.length-1 do %>
      <tr>
        <td><%=h @foo[i].id %></td>
        <td><%=h @foo[i].length %></td>
        <td><% if (i==@foo.length-1) 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.

    0 讨论(0)
提交回复
热议问题