SQLite 3 Tree List Without CTE - sqlite

I adapted a SQL statement to work with SQLite 3. But unfortunately Common Table Expressions and WITH clause works only in SQLite 3.6 ahead, but the users of my Open Source application are using SQLite 3.2 and I cannot force them to update the whole Linux system to get the new packages. Is it possible to adapt the code to work without using a CTE and "With" Clause using only SQL Language?
Here's the code:
WITH
cte AS
(SELECT 0 AS level, collectionID, collectionName, parentCollectionID, CAST(collectionID AS VARCHAR(128)) AS Sort
FROM collections WHERE parentCollectionID IS NULL
UNION ALL
SELECT p.level + 1, c.collectionID, c.collectionName, c.parentCollectionID, CAST(p.Sort || '/' || CAST(c.collectionID AS VARCHAR) AS VARCHAR(128))
FROM collections c
INNER JOIN cte p ON p.collectionID = c.parentCollectionID)
SELECT
collectionID,
printf('%*s', level * 4, '') || collectionName AS collectionName,
Sort,
parentCollectionID
FROM cte
ORDER BY Sort;
Here's the result:
collectionID collectionName Sort parentCollectionID
1 Dissertação 1 0
10 Filosofia Reformacional 10 0
11 Dooyeweerd 11 0
14 ZotPad favorites 14 0
15 Diversos 15 0
2 Bíblia 2 0
3 Políticas Públicas 3 0
4 Zotero 4 0
5 Linux 5 0
6 Tese Doutorado 6 0
12 Pontal Do Paraná 6/12 6
7 Multimodal 6/7 6
13 Modalidades 6/7/13 7
8 Base Histórica 6/7/8 7
9 Artigo Weber 9 0
Thank you so much,
Best regards,
Christian

CTEs were added to SQLite because they cannot be emulated with any other SQL language constructs.
The recommended way of using the SQLite library is not to link to some random version that comes with the OS, but to add a copy of the sqlite3.c file directly to your application.
This prevents both version and configuration conflicts.

Related

sqlite update a column with itself

I got a table like this
a b c
-- -- --
1 1 10
2 1 0
3 1 0
4 4 20
5 4 0
6 4 0
The b column 'points' to 'a', a bit like if a is the parent.
c was computed. Now I need to propagate the parent c value to their children.
The result would be
a b c
-- -- --
1 1 10
2 1 10
3 1 10
4 4 20
5 4 20
6 4 20
I can't make an UPDATE/SELECT combo that works
So far I got a SELECT that procuce the c column I'd like to get
select t1.c from t t1 join t t2 on t1.a=t2.b;
c
----------
10
10
10
20
20
20
But I dunno how to stuff that into c
Thanx in advance
Cheers, phi
You have to look up the value with a correlated subquery:
UPDATE t
SET c = (SELECT c
FROM t AS parent
WHERE parent.a = t.b)
WHERE c = 0;
I finnally found a way to copy back my initial 'temp' SELECT JOIN to table 't'. Something like this
create temp table u as select t1.c from t t1 join t t2 on t1.a=t2.b;
update t set c=(select * from u where rowid=t.rowid);
I'd like to know how the 2 solutions, yours with 1 query UPDATE correlated SELECT, and mine that is 2 queries and 1 correlated query each, compare perf wise. Mine seems more heavier, and less aesthetic, yet regarding perf I wonder.
On the Algo side, yours take care not to copy the parent data, only copy child data, mine copy parent on itself, but that's a nop, yet consuming some cycles :)
Cheers, Phi

R Programming - Update mysql db rows where a condition is met

I have a data frame that is structured identical to a table in my mysql db. I want to update the rows of the mysql db where the primary key of my data frame and that table match.
For example
DF 1
PK Count Temperature
3 1 111
4 2 100
5 3 190
6 4 200
MySQL Table
PK Count Temperature
1 1 100
2 10 11
3 0 0
4 0 0
5 0 0
6 0 0
7 0 0
8 0 0
Notice that I can't simply overwrite the table because I have rows in my DB that do not exist in my data frame.
After the update, what I would like to have is the following table.
PK Count Temperature
1 1 100
2 10 11
3 1 111
4 2 100
5 3 190
6 4 200
7 0 0
8 0 0
Thoughts?
So, I haven't been able to directly update a row. However, what I have done is create a holding table in my DB that I can append to from R. I then created a trigger in my db to update the desired rows in my desired table. From their, I have created another trigger to empty my holding table.
This is sort of what Dean was suggesting, but a little different.
Here, I am providing alternative approach over writing frame to a temp table and performing update in the main table or getting holding table, append, and update desired table by trigger method.
I believe following approach is easy and effective as it performs update record directly in the target table.
#install.packages("RMySQL")
#install.packages("DBI")
library(DBI)
library(RMySQL)
#Establish the connection
mydb = dbConnect(MySQL(),
user='your user',
password='your password',
dbname='your DB name',
host='Host Name')
#Eusuring the connection working by listing table
dbListTables(mydb)
#Applying update statement directly
rs = dbSendQuery(mydb, "UPDATE DB_NAME.TABLE_1
SET FIELD_1 = 0
WHERE ID = 5")
#Verifying the result
rs = dbSendQuery(mydb, "SELECT * FROM DB_NAME.TABLE_1
WHERE ID = 5")
data = fetch(rs, n=-1)
print(data)
I have tried above code in R Studio Version 1.1.453 and R 3.5.0 (64bit).

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 )

Bill of Materials Query

I currently have 2 tables as follows within my database:
Table: SampleProducts
SampleProductsId (PK) Name
1 A
2 B
3 C
4 D
5 E
6 F
7 G
Table: SampleProductsBoms
SampleProductsBomId (PK) ParentId (FK) ChildId (FK) Quantity
1 1 2 3
2 2 3 4
3 4 6 2
ParentId and ChildId both reference SampleProductsId
In English so I can ensure that we are all on the same page:
Product A is made up of 3 of B
Product B is made up of 4 of C
Product D is made up of 2 of F
I would like to create a Stored Procedure / LinQ statement or something which I can use in my MVC 3 c# Web Application which will give me the following table structure / object to use...
Example:
Recursive Query to find the components of B
ProductId Name Quantity
3 C 4
6 F 2
This could go quite deep, so I really do need recursion!
CTE is helpfull for recursing as require in your problem statement check the link
Common Table Expression
or i think following query may also solve your purpose
select components.SampleProductId as productid,components.Name as Name,Quantity
from SampleProductsBOM bom
inner join SampleProducts products
on products.ParentId=bom.ParentId
inner join SampleProducts components
on components.SampleProductId=bom.ChildId
where products.Name='B'

Ref cursor with dynamic columns

I am using oracle 11g and have written a stored procedure which stores values in temporary table as follows:
id count hour age range
-------------------------------------
0 5 10 61 10-200
1 6 20 61 10-200
2 7 15 61 10-200
5 9 5 61 201-300
7 10 25 61 201-300
0 5 10 62 10-20
1 6 20 62 10-20
2 7 15 62 10-20
5 9 5 62 21-30
1 8 6 62 21-30
7 10 25 62 21-30
10 15 30 62 31-40
now using this temp table i want to return two cursors. one for 61 and one for 62(age).
and for cursors there distinct range will be columns . for example cursor for age 62 should return following as dataset.
user 10-20 21-30 31-40
Count/hour count/hour count/hour
----------------------------------------------
0 5 10 - - - -
1 6 20 8 6 - -
2 7 15 - - - -
5 - - 9 5 - -
7 - - 10 25 - -
10 - - - - 15 30
this column range in temp table is is not a fixed values these are referenced from other table.
edited: i am using PIVOT for above problem, all examples i saw in internet are there for fixed values of column values (range in my case). how can i get dynamic values. following is the ex query:
SELECT *
FROM (SELECT column_2, column_1
FROM test_table)
PIVOT (SUM(column1) AS sum_values FOR (column_2) IN ('value1' AS a, 'value2' AS b, 'value3' AS c));
Instead of using handwritten value i am using following query inside 'IN'
SELECT * from(
with x as (
SELECT DISTINCT range
FROM test_table
WHERE age = 62 )
select ltrim( max( sys_connect_by_path(range, ','))
keep (dense_rank last order by curr),
',') range
from (select range,
row_number() over (order by range) as curr,
row_number() over (order by range) -1 as prev
from x)
connect by prev = PRIOR curr
start with curr = 1 )
it is giving error in this case. But when i using handwritten values its giving right output.
select * from (select user_id, nvl(count,0) count, nvl(hour,0) hour,nvl(range,0) range,nvl(age,0)
age from test_table)
PIVOT (SUM(count) as sum_count, sum(hour) as sum_hour for (range) IN
(
'10-20','21-30','31-40'
)
) where age = 62 order by userid
how can i give values dynamically there?
how can i do it.
Cursors are slow, I would recommend trying to do this in a query unless there's no alternative (or speed doesn't matter). You may want to look into: PIVOT / UNPIVOT which can rotate columns (in this case "range").
Here's some PIVOT / UNPIVOT documentation and examples:
http://www.oracle-developer.net/display.php?id=506
Based on your last edit:
Pretty sure you have two options:
Build dynamic sql based on the distinct values found in the "range" column.
You'll probably be stuck using a cursor again to build the column names but at least it will be limited to just the distinct ranges.
Oracle has a PIVOT XML command that you can use for this.
See: http://www.oracle.com/technetwork/articles/sql/11g-pivot-097235.html
And scroll down to the section: "XML Type"

Resources