Let's say that I have sql table like this:
id | val_1 | val_2
1 | 55 | 300
2 | 90 | 600
3 | 80 | 200
..
Now, I wan't to subtract 300-90, and next 600-80 and so on with offset of one row. Table can be odd count like this. Is there a chance to do this without loop and external functions? I use Python api for sqlite3.
Thanks in advance!
Depending on the output that you want you can use LEAD() window function:
SELECT *,
val_2 - LEAD(val_1, 1, 0) OVER (ORDER BY id) AS difference
FROM tablename;
or LAG() window function:
SELECT *,
LAG(val_2, 1, 0) OVER (ORDER BY id) - val_1 AS difference
FROM tablename;
See the demo.
Related
I have a dataset like shown below (except the Ser_NO, this is the field i want to create).
+--------+------------+--------+
| CaseID | Order_Date | Ser_No |
+--------+------------+--------+
| 44 | 22-01-2018 | 1 |
+--------+------------+--------+
| 44 | 24-02-2018 | 3 |
+--------+------------+--------+
| 44 | 12-02-2018 | 2 |
+--------+------------+--------+
| 100 | 24-01-2018 | 1 |
+--------+------------+--------+
| 100 | 26-01-2018 | 2 |
+--------+------------+--------+
| 100 | 27-01-2018 | 3 |
+--------+------------+--------+
How can i achieve a serial number for each CaseId based on my dates. So the first date in a specific CaseID gets number 1, the second date in this CaseID gets number 2 and so on.
I'm working with T-SQL btw,
I've tried a few things:
CASE
WHEN COUNT(CaseID) > 1
THEN ORDER BY (Order_Date)
AND Ser_no +1
END
Thanks in advance.
First of all, although I don't understand what you did, it gives you what you wanted. The serial number is assigned by date order. The problem I can see is that the result shows you the rows in the wrong order (1, 3, 2 instead of 1, 2, 3).
To sort that order you can try this:
SELECT *, ROW_NUMBER() OVER (PARTITION BY caseid ORDER BY caseid, order_date) AS ser_no
FROM [Table]
Thanks for your reply,
Sorry for the misunderstanding, because the ser_no is not yet in my table. That is the field a want to calculate.
I finished it myself this morning, but it looks almost the same like your measure:
RANK() OVER(PARTITION BY CaseID ORDER BY CaseID, Order_Date ASC
I have the following table:
date | id
-----------|------
unixtime_1 | 2
unixtime_1 | 7
unixtime_1 | 9
unixtime_1 | 24
unixtime_1 | 29
unixtime_1 | 21
unixtime_2 | 8
So far I get the results from such a table doing so:
SELECT date, id FROM table ORDER BY date DESC, id ASC
and I get
unixtime_1 | 2
unixtime_1 | 7
unixtime_1 | 9
unixtime_1 | 21
unixtime_1 | 24
unixtime_1 | 29
unixtime_2 | 8
I was wondering whether I could LIMIT the result so that in the range id=1-10 id=11-20 and id=21-30 I could get in the result only the record with the higher id.
So:
unixtime_1 | 9
unixtime_1 | 29
Since for id range=11-20 there isn't any record, it should be skip the range.
The range now are 1-10, 11-20, 21-30 but are custom ranges set by me according to the user request so I should be able to change them.
Is that possible via query?
Thank you
Your latest requirement should be possible to achieve merely by grouping by the date and (id - 1) / <some_number>, where in your example <some_number> would be 10.
SELECT t1.*
FROM yourTable t1
INNER JOIN
(
SELECT date, (id - 1) / 10 AS id_grp, MAX(id) AS max_id
FROM yourTable
GROUP BY date, (id - 1) / 10
) t2
ON t1.date = t2.date AND t1.id = t2.max_id
ORDER BY
t1.date, t1.id;
You may choose any range you want 1 - num by simply replacing 10 in my query with the end of the range.
If i did understand correctly and if your range is id=1-3
you could simply do:
SELECT id, date FROM table WHERE id>=1 AND id<=3 ORDER by id DESC, date DESC limit 1;
this will give you only 1 record with the highest id in the range id=1-3.
you can store it and perform another query for another range and combine them later
Try this:
SELECT date, MAX(ID) FROM table GROUP BY date
How can I create a column that has ranked the information of the table based on two or three keys?
For example, in this table the rank variable is based on Department and Name:
Dep | Name | Rank
----+------+------
1 | Jeff | 1
1 | Jeff | 2
1 | Paul | 1
2 | Nick | 1
2 | Nick | 2
I have found this solution but it's in SQL and I don't think it applies to my case as all information is in one table and the responses seem to SELECT and JOIN combine information from different tables.
Thank you in advance
You can count how many rows come before the current row in the current group:
UPDATE MyTable
SET Rank = (SELECT COUNT(*)
FROM MyTable AS T2
WHERE T2.Dep = MyTable.Dep
AND T2.Name = MyTable.Name
AND T2.rowid <= MyTable.rowid);
(The rowid column is used to differentiate between otherwise identical rows. Use the primary key, if you have one.)
I have a sample table with following values
SNO | Mon
-----+-------
100 | 1
101 | 1
102 | 1
100 | 2
101 | 2
102 | 2
100 | 3
101 | 3
Now I need a query to count the total sno's which are in 3 months
The result should be 2, as 100 & 101 are in mon 1,2 and 3. However, 102 is only present in mon 1,2.
Thanks,
RK
This Query in theory should work.
SELECT
tmpTbl.sNo
FROM
tmpTbl
GROUP BY
tmpTbl.sNo
HAVING
Count(tmpTbl.monNo) = (SELECT Count(*) FROM (SELECT tmpTbl.monNo FROM tmpTbl GROUP BY tmpTbl.monNo));
The result would be,
sNo
----
100
101
I have used two SubQueries to get the result. Teh both are used in the HAVING clause of the SQL. First SqubQuery (inner most). Will get the number of Unique Month's available in your table, the outer SubQuery will then Count the number of Unique months. So the Overall Query can be translated as "SELECT the serial number FROM the table HAVING the Count of Month equal to the Number of unique records in the same table".
The reason I used SbQuery instead of a number is because of the fact this will also be applicable when your month number increases. Hope this helps !
EDIT
Here is the Query for getting the count.
SELECT
Count(*) As simpleCount
FROM
(
SELECT
tmpTbl.sNo
FROM
tmpTbl
GROUP BY
tmpTbl.sNo
HAVING
Count(tmpTbl.monNo) = (SELECT Count(*) FROM (SELECT tmpTbl.monNo FROM tmpTbl GROUP BY tmpTbl.monNo))
);
I have a table with this structure:
id | IDs | Name | Type
1 | 10 | A | 1
2 | 11 | B | 1
3 | 12 | C | 2
4 | 13 | D | 3
except id nothing else is a FOREIGN or PRIMARY KEY. I want to select a row based on it's column values that are not PRIMARY KEY. I have tried the following syntax but it yields no results.
SELECT * FROM MyTable WHERE Name = 'A', Type = 1;
what am I doing wrong? What is exactly returned by a SELECT statement? I'm totally new to Data Base and I'm currently experimenting and trying to learn it. so far my search has not yield any results regarding this case.
Use and to add multiple conditions to your query
SELECT *
FROM MyTable
WHERE Name = 'A'
AND Type = 1;