Pergunta

I looked through the questions here but didn't find one that suited my case.

I'm trying to write a query that will output the difference between rows

Here is a table:

ITEM     CYCLES
--------------------
itemA     5
itemA     17
itemA     20  
itemA     22
itemB     26
itemB     30
itemB     37

it is actually obtained by a query, and with an order by (item, cycles)

here is what I'd like the query to give me:

itemA 12
itemA 3
itemA 2
itemB 4
itemB 7

I have absolutely no idea how to proceed in SQL. Is it even possible ? or do I have to write a function ?

*****************************EDIT*********************************

I appologize for the lack of precision, and even some absurd mistakes. I was rushing out and wrote hastily :/
I'm analyzing item failures, and need to output cycles between failures.

  • ITEM column is just the item ID, and
  • CYCLES is the number of cycles the item had when the failure occurred.

And actually looking at it today I don't understand why I put that middle column (A,B,C...) which I don't have in my table.
And indeed, I don't need to output zero values, but there shouldn't be any anyway. I'll try the provided solutions and will get back; thanks for the answers !

Foi útil?

Solução

Here's an updated solution, based on the changes to your question. Note that you'll need to change Qry to the name of your query:

SELECT Qry.Item, Qry.Cycles - (SELECT TOP 1 Cycles FROM Qry AS Q 
                               WHERE Qry.Item=Q.Item
                                 AND Q.Cycles < Qry.Cycles 
                               ORDER BY Q.Cycles DESC) AS Diff
FROM Qry
WHERE (SELECT TOP 1 Cycles FROM Qry AS Q 
       WHERE Qry.Item=Q.Item AND Q.Cycles < Qry.Cycles) Is Not Null
ORDER BY Qry.Item, Qry.Cycles;

This produces the following output:

Item    Diff
itemA   12
itemA    3
itemA    2
itemB    4
itemB    7

I assume that the 6 in your sample output was a typo, since 30 - 26 = 4.

Outras dicas

Assuming our columns are named ItemName, Letter, Num, something like the following might do it:

SELECT T1.ItemName, T1.Letter
    , T1.Num, [T2].[Num]-Nz([T1].[Num],[T2].[Num]) AS Expr1
FROM Table1 AS T1 
    LEFT JOIN Table1 AS T2 
        ON (T1.ItemName = T2.ItemName 
            And Asc([T1].[Letter]) = Asc([T2].[Letter]) - 1 )
Where  [T2].[Num] <> Nz([T1].[Num],[T2].[Num])

Note that you cannot create this using the QBE grid. You would need to create in code or in the SQL View.

How about:

SELECT b.Item, b.[No], (
   SELECT Top 1 a.No 
   FROM items a 
   WHERE a.No > b.No  
   ORDER BY a.Item,a.No) AS NextNo, 
[NextNo]-[No] AS Result
FROM items AS b;

This is much simpler if you have a fourth column with an ID:

Col0 Col1  Col2 Col3
1   itemA   A    5
2   itemA   B   17
3   itemA   C   20
4   itemA   D   22
5   itemB   A   26
6   itemB   B   30
7   itemB   C   37

Then you can use the following query:

SELECT Tbl.Col1, Tbl.Col3 - Prev.Col3 AS Diff
FROM Tbl INNER JOIN Tbl AS Prev 
  ON Tbl.Col0 - 1 = Prev.Col0 
 AND Tbl.Col1 = Prev.Col1

To produce exactly what you requested:

Col1    Diff
itemA   12
itemA    3
itemA    2
itemB    4
itemB    7

You would need to manage the Col0 data to make sure you don't end up with gaps (ie, Autonumber field would be a bad idea).

All of the above having been said, if you let us know what you are really trying to accomplish I'm thinking there is probably a better way to do what you want.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top