find the difference between current and previous value - postgresql - sql

I'm trying to write a query that will show me the difference between the current value and the previous one from the query result. It seems to me that this can be done with the "OFFSET" or "LEAD" method. But I don't understand how.
Исходная таблица.
Name Number Dictionary
---
Kate 300 Dict1
Helena 200 Dict1
Michael 150 Dict1
John 100 Dict2
I want to select only data for Dict1 in my query, while in the new column I need to see the difference between the current and previous values from the result of the "Number" query
select * from table
where Dictionary='Dict1'
Name Number Dictionary Difference value
---
Kate 300 Dict1 100 #(300-200)
Helena 200 Dict1 50 #(200-150)
Michael 150 Dict1 150 #(150-null)

This is working for me by partitioning over the dictionary itself.
SELECT name, number, dictionary,
number - LEAD(number,1) OVER (PARTITION BY dictionary) as "Difference_value"
FROM users
WHERE dictionary = 'Dict1';
It also solves the issue of the last row being extracted from the first one (300-150).
The last line with the explicit WHERE is optional if you want to see the difference for Dict2 as well.
DB-Fiddle

Use the window function LEAD
SELECT *, number - COALESCE(LEAD(number) OVER w,0)
FROM t
WHERE dictionary = 'Dict1'
WINDOW w AS (PARTITION BY dictionary ORDER BY number DESC
ROWS BETWEEN CURRENT ROW AND 1 FOLLOWING);
Demo: db<>fiddle

Related

How to get a row number from entry in results - SQLite?

In SQLite how do I get the row number of a specific result?
Consider my data is the following
Username UserLevel
James 23
Tim 24
John 22
What I'd like to return is the position in the statement where said person is. IE
Select * from users where Username='John' (+ SOME LOGIC);
Returns
3
Thanks!
you can use ROW_NUMBER(). ROW_NUMBER is a temporary value calculated when the query is run

HANA concat rows

I use SAP-HANA database. I have a simple 2 column table whose columns are number, name, noodles, fish . The rows are these:
number name noodles fish
1 tom x
1 tom x
1 jack
2 jack x
I would like to group the rows by the id, and concatenate the names into a field, and thus obtain this:
number name noodles fish
1 tom x x
2 jack x
Can you please tell me how we can perform this operation in sap-hana? Thanks in advance.
Well, you did not really concatenate the names, but instead kept the same ones (if you would have concatenated the names as well, you would get something like jackjack in your result). I guess your x's indicate some sort of ABAP-style flags.
In any case, you would do this with grouping. This is a completely non-HANA thing (you can use the same basic SQL for any DB). You can group against several columns. All other columns that you want to select must be used in an aggregated expression (e.g. a SUM, MAX, COUNT, etc.).
To get the output from your question, I wrote the following code:
SELECT "ID", "NAME", MAX("FISH"), MAX("NOODLES")
FROM #TEST GROUP BY "ID", "NAME";
And got the same output as you. I used the MAX function based on the following assumption: you would want to get X if there is any X in the "concatenated" (aggregated) rows in that column. You get nothing / space if all the "concatenated" rows have space in them.

How to Pivot rows into columns using Decode where the content is variable

I'm having some trouble with formatting so hopefully my description makes sense. I am writing a query for an Oracle DB that doesn't support the Pivot function, but I have used Decode in the past to achieve a similar result.
The query so far returns a table of 2 columns, the first is a text label, the second is an item number. Every row will contain a label and an item number, the item numbers will each be unique but the labels will repeat.
For example
A - 101
B - 102
A - 103
C - 104
B - 105
A - 106
I would like to pivot this so I have one row for each text label and as many columns as necessary to show all the matching item numbers. So the table would look like
A - 101 - 103 - 106
B - 102 - 105
C - 104
The quantity of numbers that need to be pivotted is variable, as are the item numbers themselves. Is this possible to do using the decode function, or any other function?
Sentinel's link in the comments contained the answer I was looking for, see here ORACLE-BASE
My database version 10.2 does not have the LISTAGG function but it does have the WM_CONCAT function so my query becomes
select label, WM_CONCAT(item_number)
from table
group by label

Average Distinct Values in a single column in Power Pivot

I have a column in PowerPivot that basically goes:
1
1
2
3
4
3
5
4
If I =AVERAGE([Column]), it's going to average all 8 values in the sample column. I just need the average of the distinct values (i.e., in the example above I want the average of (1,2,3,4,5).
Any thoughts on how to go about doing this? I tried a combination of =(DISTINCT(AVERAGE)) but it gives a formula error.
Thanks!!
Kevin
There must be a cleaner way of doing this but here is one method which uses a measure to get the sum of the values divided by the number of times it appears (to basically give the original value) then uses an iterative function to do it for each unique value.
Apologies for the uninspired measure names:
[m1] = SUM(table1[theValue]) / COUNTROWS(Table1)
[m2] = AVERAGEX(VALUES(Tables1[theValue]), [m1])
Assuming your table is caled table1 and the column is called theValue

Access SQL how to make an increment in SELECT query

I Have an SQL query giving me X results, I want the query output to have a coulmn called
count making the query somthing like this:
count id section
1 15 7
2 3 2
3 54 1
4 7 4
How can I make this happen?
So in your example, "count" is the derived sequence number? I don't see what pattern is used to determine the count must be 1 for id=15 and 2 for id=3.
count id section
1 15 7
2 3 2
3 54 1
4 7 4
If id contained unique values, and you order by id you could have this:
count id section
1 3 2
2 7 4
3 15 7
4 54 1
Looks to me like mikeY's DSum approach could work. Or you could use a different approach to a ranking query as Allen Browne described at this page
Edit: You could use DCount instead of DSum. I don't know how the speed would compare between the two, but DCount avoids creating a field in the table simply to store a 1 for each row.
DCount("*","YourTableName","id<=" & [id]) AS counter
Whether you go with DCount or DSum, the counter values can include duplicates if the id values are not unique. If id is a primary key, no worries.
I frankly don't understand what it is you want, but if all you want is a sequence number displayed on your form, you can use a control bound to the form's CurrentRecord property. A control with the ControlSource =CurrentRecord will have an always-accurate "record number" that is in sequence, and that will update when the form's Recordsource changes (which may or may not be desirable).
You can then use that number to navigate around the form, if you like.
But this may not be anything like what you're looking for -- I simply can't tell from the question you've posted and the "clarifications" in comments.
The only trick I have seen is if you have a sequential id field, you can create a new field in which the value for each record is 1. Then you do a running sum of that field.
Add to your query
DSum("[New field with 1 in it]","[Table Name]","[ID field]<=" & [ID Field])
as counterthing
That should produce a sequential count in Access which is what I think you want.
HTH.
(Stolen from Rob Mills here:
http://www.access-programmers.co.uk/forums/showthread.php?p=160386)
Alright, I guess this comes close enough to constitute an answer: the following link specifies two approaches: http://www.techrepublic.com/blog/microsoft-office/an-access-query-that-returns-every-nth-record/
The first approach assumes that you have an ID value and uses DCount (similar to #mikeY's solution).
The second approach assumes you're OK creating a VBA function that will run once for EACH record in the recordset, and will need to be manually reset (with some VBA) every time you want to run the count - because it uses a "static" value to run its counter.
As long as you have reasonable numbers (hundreds, not thousands) or records, the second approach looks like the easiest/most powerful to me.
This function can be called from each record if available from a module.
Example: incrementingCounterTimeFlaged(10,[anyField]) should provide your query rows an int incrementing from 0.
'provides incrementing int values 0 to n
'resets to 0 some seconds after first call
Function incrementingCounterTimeFlaged(resetAfterSeconds As Integer,anyfield as variant) As Integer
Static resetAt As Date
Static i As Integer
'if reset date < now() set the flag and return 0
If DateDiff("s", resetAt, Now()) > 0 Then
resetAt = DateAdd("s", resetAfterSeconds, Now())
i = 0
incrementingCounterTimeFlaged = i
'if reset date > now increments and returns
Else
i = i + 1
incrementingCounterTimeFlaged = i
End If
End Function
autoincrement in SQL
SELECT (Select COUNT(*) FROM table A where A.id<=b.id),B.id,B.Section FROM table AS B ORDER BY B.ID Asc
You can use ROW_NUMBER() which is in SQL Server 2008
SELECT ROW_NUMBER() OVER (ORDER By ID DESC) RowNum,
ID,
Section
FROM myTable
Then RowNum displays sequence of row numbers.