How to subtract the content of a column of two rows - sql

I have a table like this
and I want to return the difference between the two rows

SQL tables represent unordered sets. There is no ordering, unless a column specifies the ordering.
So, you can get the two values using MAX() and MIN(). This should do what you want:
select max(nbaction) - min(nbaction)
from t;
EDIT:
Given your actual problem, you have multiple choices. Here is one:
SELECT (SELECT nbaction
FROM analyse_page_fait
WHERE operateurdimid = 2
ORDER BY datedimid DESC
FETCH FIRST 1 ROW ONLY
) -
(SELECT nbaction
FROM analyse_page_fait
WHERE operateurdimid = 2
ORDER BY datedimid DESC
OFFSET 1
FETCH FIRST 1 ROW ONLY
) as diff

Related

Selecting all rows that have a value in the top N rows

Consider this simple table of event counts:
event_name
count
viewLoaded
20
viewUnloaded
17
buttonTapped
12
viewScrolled
12
networkSuccess
9
linkTapped
9
networkFailure
2
leapSecond
0
I would like to select the top N events by count, but with the additional requirement that if the result set includes any event with a particular count, then it should include all of the events with that count. In other words, I don’t want to break up any of the “groups” of rows that have the same count. Instead, I will potentially get more rows than I asked for.
For example, if I wanted the “top five” events in the table above, the query would actually return six rows so that both events with count 9 were included. The query for the top four would return four rows, and the query for the top three would also return four rows.
How can I accomplish this in SQLite?
You can use the RANK window function for this task. It's ranking value will be equal for the identical values, but will consider the amount of past rows when needs to assign the next ranking.
WITH cte AS (
SELECT *, RANK() OVER(ORDER BY count_ DESC) AS rn
FROM events
)
SELECT event_name, count_ FROM cte WHERE rn <= 5
Check the demo here.
One way is to use a common table expression to identify the counts corresponding to the “top five” events:
with top_five as (
select count from events order by count desc limit 5
)
select * from events where count in top_five order by count desc;

How to check max from range in cursor?

I have a problem with transferring an Excel formula to SQL. My excel formula is: =IF(P2<(MAX($P$2:P2));"Move";"").
The P column in excel is a sequence of numbers.
a | b
------
1
2
7
3 MOVE
4 MOVE
8
9
5 MOVE
10
You can find more example on this screenshot:
I created a cursor with a loop but I don't know how to check max from range.
For example when I iterate for fourth row, I have to check max from 1-4 row etc.
No need for a cursor and a loop. Assuming that you have a column that defines the ordering of the rows (say, id), you can use window functions:
select t.*,
case when a < max(a) over(order by id) then 'MOVE' end as b
from mytable t
One option would be using MAX() Analytic function . But in any case, you'd have an extra column such as id for ordering in order to determine the max value for the current row from the first row, since SQL statements represent unordered sets. If you have that id column with values ordered as in your sample data, then consider using
WITH t2 AS
(
SELECT MAX(a) OVER (ORDER BY id ROWS BETWEEN
UNBOUNDED PRECEDING
AND
CURRENT ROW) AS max_upto_this_row,
t.*
FROM t
)
SELECT a, CASE WHEN max_upto_this_row > a THEN 'Move' END AS b
FROM t2
ORDER BY id;
Demo

I want to find the longest varchar in a specific column of a SQL Server table

Here's an example:
ID = INT IDENTITY
DESC = VARCHAR(5000)
ID | Desc
---|-----
1 | a
2 | aaa
3 | aa
The SQL query here should return 3 and the word itself i.e., aaa? Since the longest value is aaa with 3 characters?
The output should be:
aaa 3
You can use order by and limit the results to one row:
select description, len(description)
from t
order by len(description) desc
offset 0 row fetch first 1 row only;
Or use:
select top (1) description, len(description)
from t
order by len(description) desc;
With OFFSET & FETCH:
OFFSET is specifying how many rows from the top of the result set you will ignore ...
And then the FETCH is used to limit the result to the number of rows you specify.
The combination of this two will return the desired result because the result set is ordered by len(descr).
select descr, len(descr)
from test
order by len(descr) desc
OFFSET 0 ROWS
fetch first 1 rows only;
With TOP:
TOP will limit the reultset to the number of rows you specify. In this example 1. Because it is ordered by the lenght of the column desc then the first row will be the one you are looking for.
select top 1 descr, len(descr)
from test
order by len(descr) desc
HERE IS A DEMO for both examples
Note for the end:
Use aliases (I will demonstrate on one of this two examples)
select descr as Description, len(descr) "Description length"
from test
order by len(descr) desc
OFFSET 0 ROWS
fetch first 1 rows only;
You can put them between double quotes or not, use keyword as or not, it is up to you but the result looks better with them.
Both ROW and ROWS keyword is ok for OFFSET and FETCH clause. So what ever you want to use you can...
You can try TOP as shown below. Here is the official documentation of TOP (Transact-SQL).
Select
top 1 Id, description, len(description) as MaxLength
from YourTable order by len(description) desc
Live Demo
This will do what you want on Oracle (one of the tags on the question):
SELECT descript,length(descript)
FROM t WHERE length(descript)=( SELECT max(length(descript)) FROM t);
Keep in mind that if there are two (or more) records with that length, you will get them all. You could add a AND rownum < 2 clause but that will give you which ever entry the database chooses to give.
If you want the first record of those with the longest field, a subquery will be required:
SELECT descript,length(descript) from (
select descript from t order by length(descript) desc, descript asc)
WHERE rownum < 2;
There is also the offset 0 row fetch... version listed earlier:
SQL> select descript, length(descript)
2 from t
3 order by length(descript) desc
4 offset 0 row fetch first 1 row only;
DESCRIPT LENGTH(DESCRIPT)
-------------------- ----------------
defg 4
Mind you, this only works on my "12.2.0.1.0" Oracle. If I try the same thing on my "11.2.0.4.0" Oracle, I get "ORA-00933: SQL command not properly ended" with that last line. Apparently this is newer, maybe that is why I have never seen it before.

How can I convert 2 row into column in tsql?

I have 2 row data which I want to make it to be 2 column,
I tried union syntax but it didn't work.
Here is the data I have:
breed 1 breed2
I tried to convert it with this sql
select a.breed union a.breed
but it didn't work.
Here is what you want from the SQL:
breed1,breed2
SELECT
[breed1],
[breed2]]
FROM
(
SELECT 'breed1' myColumn
union
select 'breed2'
) AS SourceTable
PIVOT
(
AVG(mySecondColumn) FOR
myColumn IN ([breed1], [breed2]])
) AS PivotTable;
You can use a self join. This needs a way to pair rows together (so if you have four rows you get 1 and 2 in one result and 3 and 4 in the other rather than another combination).
I'm going to assume you have sequentially numbered rows in an Id column and an odd numbered row is paired with the one greater even Id:
select odd.Data as 'First', even.Data as 'Second'
from TheData odd
inner join TheData even on odd.Id+1 = even.Id
where odd.Id % 2 = 1;
More generally for more columns use of pivot is more flexible.
How about an aggregation query?
select min(breed) as breed1, max(breed) as breed2
from t;

PostgreSQL:How get last rows from a select query

See the below example,
create table data(name varchar, value int);
insert into data values('joe',1);
insert into data values('bob',2);
insert into data values('jane',3);
insert into data values('anne',4);
insert into data values('kate',5);
And if I Execute
select * from data limit 2;
Will Get
name | value
------+-------
joe | 1
bob | 2
(2 rows)
So,How Can I Get the Last 2 Rows in select * from data?
What I'm expecting is....
name | value
------+-------
anne | 4
kate | 5
(2 rows)
You have two options according to your need i.e,
select * from data order by value desc limit 2
Or
LIMIT and OFFSET
if you want the 4th and 5th row just offset the first 3 so that the 4th row becomes the start of our set and you can specify a limit to say that you only want 2 rows from that.
select * from data offset 3 limit 2;
/* The order of LIMIT and OFFSET does not matter. This gives the same result */
select * from data limit 2 offset 3;
I know I'm answering a six year old question and I know the accepted answer says to use an offset, however that's only going to be useful if you know the length of the table. Looking at the wording of the question and the example given, I assumed that like myself, the author wanted the last entries in a table based on an id or other value in the order that they were entered.
The best solution I've found so far that orders the values as expected is using a subquery as follows:
SELECT * FROM ( SELECT * FROM data ORDER BY VALUE DESC LIMIT 2) AS _ ORDER BY VALUE ASC;
You'd substitute VALUE for whichever column you'd want to sort by to get the "last" entries. In my experience, this method is an order of magnitude quicker than using a count to find an offset.
To get the x last rows, example with x=10,
use offset alone, with count:
SELECT *
FROM data
ORDER BY value ASC
OFFSET (SELECT count(*) FROM DATA)-10
I let you check if the offset is not negative...
Make use of Order by Clause
select * from data order by value desc limit 2;
OR
select top 2 * from data order by value desc ;
You can achieve it using Order by clause desc
SELECT *
FROM data
ORDER BY value DESC limit 2;
like does Krishraj Rana you can try this function for get the last row with "limit 1" and order by "x col" desc, complete it "by x_col desc limit 1".