how to select and sort in sqlite and js - sqlite

Hi I have the following table
buildingcode flatname flatdescription date
01 A 1 name 1 12-2012
01 B 2 name 1 12-2012
02 A 0 name 2 12-2012
01 A 1 name 1 11-2012
I want to display as follow
B 2 name 1
A 1 name 1
And to explain what I want to do:
display only buildingcode 01,
display once by flatname,
sort by flatname desc
What is the sqlite command to do this?
I try this but the order is wrong
'SELECT DISTINCT flatdescription, flatname, buildingcode FROM bill WHERE buildingcode = ? '
Please advice

SELECT flatname, flatdescription
FROM bill
WHERE buildingcode = '01'
ORDER BY flatname DESC

Related

Teradata Retain value till next Change

I need to store the previous value in a column till there is a change and in case of change it would retain the new value
Example
Input
-------
ID Name Stdt EndDt
1 A 20/01/2019 20/02/2019
1 B 20/02/2019 20/03/2019
1 C 20/03/2019 15/05/2019
1 C 15/05/2019 16/05/2019
1 C 16/05/2019 19/06/2019
1 C 19/06/2019 15/07/2019
1 A 15/07/2019 NULL
Output
----------
ID Name Stdt EndDt Previous Name
1 A 20/01/2019 20/02/2019 NULL
1 B 20/02/2019 20/03/2019 A
1 C 20/03/2019 15/05/2019 B
1 C 15/05/2019 16/05/2019 B
1 C 16/05/2019 19/06/2019 B
1 C 19/06/2019 15/07/2019 B
1 A 15/07/2019 NULL C
Tried preceding and self joins but those are limited to know number of changes (like name can remain constant for N times) but need more dynamic
You need nested Window functions:
SELECT ...
-- assignt the previous value to all following rows
Last_Value(CASE WHEN prev_name <> NAME THEN prev_name END IGNORE NULLS)
Over (PARTITION BY id
ORDER BY stdt, enddt) as previous_name
FROM
(
SELECT ...
-- flag the changed row
Lag(NAME) Over (PARTITION BY id ORDER BY stdt, enddt) AS prev_name
-- pre-TD 16.10
-- MIN(NAME)
-- Over (PARTITION BY id ORDER BY stdt, enddt
-- ROWS BETWEEN 1 Preceding AND 1 Preceding) AS prev_name
FROM mytable
) AS dt
thanks a lot for the solution it worked like a charm.
P.S : Sorry I was away on a vacation and the requirement changed a bit so didn't checked this solution provided.
Thanks again blessing us with your knowledge all the time :)
Regards
Anindya

CAPTURE CHANGE AT SOURCE LEVEL

Consider a source table(ORA 11g) with BATCH ID 1 with 3 records for day 1. Say these are getting loaded into a target table. Imagine on day 2 there are 3 more customer entries with batch ID 2. Can I write a SQL query which will be enable the source node to check the target if the BATCH_ID is existing and if not read and process that BATCH_IDs records through the code?
SRC TBL(say day1)
Batch_no | ID
1 | xx
1 | yy
1 | zz
TGT TBL(EOD Day1)
Batch_no | ID
1 | xx
1 | yy
1 | zz
SRC TBL(Day 2)
Batch_no|ID
1 |xx
1 |yy
1 |zz
2 |aa
2 |bb
2 |cc
This is what I found. Thank you for your help.
SELECT required fields
FROM
"SRC TBL"
LEFT JOIN "TGT TBL"
ON "SRC TBL".BATCH_ID="TGT TBL".BATCH_ID
WHERE "TGT TBL".BATCH_ID IS NULL

sqlite: select display few rows around matching rows

I have a table of the form
select rowid,* from t;
rowid f
----- -----
1 aaa
2 bbb
3 ccc
4 ddd
5 eee
6 fff
7 ggg
8 aaa
9 bbb
10 ccc
11 ddd
12 eee
13 fff
14 ggg
Id like to select n row before and m row after a given row match, i.e for instance for rows that match f='ccc' with n=m=1 I'd like to get
2 bbb
3 ccc
4 ddd
9 bbb
10 ccc
11 ddd
The rowid is sequential in my setup so I guess we can play with it. I tried thing along the line of
select rowid,f from t where rowid between
(select rowid-1 from t where f='ccc') and
(select rowid+1 from t where f='ccc');
rowid f
----- -----
2 bbb
3 ccc
4 ddd
But the result is obviously wrong I got only the 1st occurence of the 'ccc' match. I guess I got to join or may be recursive cte, but I am affraid it is beyound my knowlegde so far :) Thanx in advance.
A scalar subquery can return only a single value.
You could do two self joins, but it would be simpler to use set operations:
SELECT * FROM t
WHERE rowid IN (SELECT rowid - 1 FROM t WHERE f = 'ccc'
UNION ALL
SELECT rowid FROM t WHERE f = 'ccc'
UNION ALL
SELECT rowid + 1 FROM t WHERE f = 'ccc');
Larger values of n and m require more subqueries.
If there are too many, you can use a join:
SELECT *
FROM t
WHERE rowid IN (SELECT t.rowid
FROM t
JOIN (SELECT rowid - ? AS n,
rowid + ? AS m
FROM t
WHERE f = 'ccc'
) AS ranges
ON t.rowid BETWEEN ranges.n AND ranges.m);
I come with a solution that is not optimal I think but I am not able to simplify (remove) the temp (intermediate) table.
select rowid,f from t;
rowid f
----- -----
1 aaa
2 bbb
3 ccc
4 ddd
5 eee
6 fff
7 ggg
8 aaa
9 bbb
10 ccc
11 ddd
12 eee
13 fff
14 ggg
create table u as
select t2.rowid x,t1.rowid+2 y from t t1 // +2 ==> 2 rows after 'ccc'
join t t2 on t1.rowid=t2.rowid+1 // +1 ==> 1 row before 'ccc'
where t1.f='ccc';
select * from u;
x y
----- -----
2 5
9 12
select t.rowid,t.f from t inner
join u on t.rowid>=u.x and t.rowid<=u.y'
rowid f
----- -----
2 bbb 1 before
3 ccc <== match
4 ddd 2 after
5 eee
9 bbb 1 before
10 ccc <== match
11 ddd 2 after
12 eee
I think I am set with what I need, but optimisations are welome :)
I might be overlooking something, but the provided solutions that suggest adding/subtracting from values of the rowid column could be improved upon. They will face issues should rowid ever be missing a value (Which I'm aware was stated to never be the case in the top post, but in general is an assumption that's often not true).
By using sqlite's row_number() you can have a solution that circumvents that problem and also can be used to fetch the entries "around" your row matches based on any arbitrary order you want, not just based on rowid.
Together with Common Table Expressions this can even be made somewhat readable, though should you have a larger amount of row-matches this will still be a slow query.
What you'll conceptually be doing is:
Do a pre-select on your table (here cte_t) to get all possible values that could be a valid hit and attach a row-number to each entry
Do a select on that pre-select to fetch the specific row that you actually want and get only its row-number (here targetRows)
"join" the two by pretty much just multiplying the two tables generated in 1) and 2).
Now you can easily select for all entries whose row-number is in a specific range around the target's row-number using ABS
WITH
cte_t AS (
SELECT *, row_number() OVER (ORDER BY t.rowid) AS rownum
FROM t
-- If you can make this cte smaller by removing all entries that can't possibly be the solution with the appropriate WHERE clause, you can make the entire query substantially faster
),
targetRows AS(
SELECT rownum AS targetRowNum
FROM cte_t
WHERE f = 'ccc' -- This should be the WHERE condition that defines the entries that match your query exactly and for which you want to get the entries around them
)
SELECT cte_t.rowid, cte_t.f
FROM cte_t, targetRows -- This is basically multiplying both tables with one another, this part will be horribly slow if targetRows gets larger
WHERE ABS(cte_t.rownum - targetRows.targetRowNum) <= 1; --Get all entries in targetRows as well as those whose rownum is 1 larger or 1 lower than the rownum of a targetRow
This will return
rowid f
2 bbb
3 ccc
4 ddd
9 bbb
10 ccc
11 ddd
Here a good resource about this.

BigQuery subsselect example (count and sum)

In google BigQuery I have done a simple query to get how many music someone has listened.
What I need is to make a sum for all rows returned from the query below (some type of subquery)?
select count(1) cnt
from OF7.PETERV_TEST
where gender='F'
group by userId
Row f0_
1 14
2 1
3 7
4 18
5 1
6 4
7 2
8 2
expected result:
49
you can use:
SELECT sum(cnt)
FROM
(SELECT count(1) cnt
FROM OF7.PETERV_TEST
WHERE gender='F'
GROUP BY userId )

SQLite query with LAST and DISTINCT

I have an example table:
ID | ArticleID | Price | SupplierID | dateAdded
1 1 100 1 2014-08-01
2 1 110 2 2014-08-01
3 2 105 1 2014-08-01
4 2 106 1 2014-08-01
5 2 101 2 2014-08-01
6 3 100 1 2014-08-01
7 1 107 2 2014-09-01
8 3 343 2 2014-09-01
9 3 232 2 2014-09-01
10 1 45 1 2014-09-01
I want to use .query on this table and select LAST value entered for each DISTINCT ArticleID for each SupplierID, resulting in:
ID | ArticleID | Price | SupplierID
10 1 45 1
9 3 232 2
6 3 100 1
7 1 107 2
4 2 106 1
5 2 101 2
I want to get price for last ArticleID entered for each SupplierID.
What should I enter into
public Cursor query (boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
I came up with this so far:
String[] columns = new String[]{DatabaseOpenHelper.KEY_ID, DatabaseOpenHelper.KEY_CENA, DatabaseOpenHelper.KEY_IZDELEK_ID};
Cursor crs = database.query(true,"prices", columns, selection, selectionArgs, null, null, null, null);
but now I'm stuck:S
Any hint how to do this?
You can also suggest raw query if possible..
Raw query would be like this:
SELECT ID, ArticleID, Price, SupplierID FROM your_table WHERE ID IN (SELECT max(ID) from your_table GROUP BY ArticleID, SupplierID);
I assumed the IDs are autoincremented and the more recent entries have higher ids. If that's not the case change the HAVING clause to operate on DATE column.
After fidling around a bit and help of a friend I have came with SQL query that does what I want, not sure about optimization:
select tab.* from cene tab inner join (
select izdelek_id, trgovina_id, Max(enter_date) as maxDate
from cene group by izdelek_id, trgovina_id) art
on (art.izdelek_id = tab.izdelek_id) and (art.trgovina_id = tab.trgovina_id) and (art.maxDate = tab.enter_date)
izdelek_id = ArticleID
trgovina_id = SupplierID
cene is the name of a table.
Hope it helps to somebody..

Resources