I have the following columns (FirstCol, SecondCol, ThirdCol) in a sqlite3 db file:
1 Inside 100
1 Outside 200
2 Inside 46
2 Outside 68
First column has type INT, second has type TEXT and third one has type INT.
For each FirstCol value (in this case just 1 and 2) i need to obtain the result of the value associated with Outside/Inside, which is to say 200/100 where FirstCol=1 and 68/46 where FirstCol=2.
I don't mind whether this is done with a single query or by creating a new table, i just need that result.
Thanks.
You have to look up the values from different rows with correlated subqueries:
SELECT FirstCol,
(SELECT ThirdCol
FROM MyTable
WHERE FirstCol = T.FirstCol
AND SecondCol = 'Outside'
) /
(SELECT ThirdCol
FROM MyTable
WHERE FirstCol = T.FirstCol
AND SecondCol = 'Inside'
) AS Result
FROM (SELECT DISTINCT FirstCol
FROM MyTable) AS T;
Related
I need Only one unique result from tableB.Field to tableA.Field
I am using sdo operator sdo_nn, this is the code:
UPDATE table1 t1
SET t1.fieldA = (SELECT T2.fieldB,SDO_NN_DISTANCE(1) distance
FROM table1 T1, table2 T2
WHERE
(sdo_nn(t1.geometry,t2.geometry,'SDO_NUM_RES=1',1)= 'TRUE')
ORDER BY DIST
)
WHERE EXISTS(
SELECT 1
FROM table2 t2
WHERE sdo_nn(t1.geometry, t2.geometry,'SDO_NUM_RES=1',1)='TRUE'
AND(t2.cell_name = 'string1' or t2.cell_name = string2')AND t1.fieldA = NULL
);
In the select sentence of the subquery i get an error because i only use one field(t1.fieldA), but in the sentence i use the operator SDO_NN_DISTANCE(1) and the sql developer count this operator like another field. What is the correct way to write this sentence? I only use sql because i need to insert this code in vba
Thanks!!!
Obviously, you can't (simplified)
set t1.fieldA = (t2.fieldB, distance) --> you want to put two values into a single column
Therefore, get fieldB alone from the subquery which uses analytic function (row_number) to "sort" rows by sdo_nn_distance(1) desc; then get the first row's fieldB value.
Something like this (I hope I set the parenthesis right):
UPDATE table1 t1
SET t1.fieldA =
(SELECT x.fieldB --> only fieldB
FROM (SELECT T2.fieldB, --> from your subquery
SDO_NN_DISTANCE (1) distance,
ROW_NUMBER ()
OVER (ORDER BY sdo_nn_distance (1) DESC) rn
FROM table1 T1, table2 T2
WHERE (sdo_nn (t1.geometry,
t2.geometry,
'SDO_NUM_RES=1',
1) = 'TRUE')) x
WHERE rn = 1) --> where RN = 1
WHERE EXISTS
(SELECT 1
FROM table2 t2
WHERE sdo_nn (t1.geometry,
t2.geometry,
'SDO_NUM_RES=1',
1) = 'TRUE'
AND ( t2.cell_name = 'string1'
OR t2.cell_name = 'string2')
AND t1.fieldA IS NULL);
I'm trying to replace a placeholder string inside a selection of 10 random records with a random string (a name) taken from another table, using only sqlite statements.
i've done a subquery in order to replace() of the placeholder with the results of a subquery. I thought that each subquery loaded a random name from the names table, but i've found that it's not the case and each placeholder is replaced with the same string.
select id, (replace (snippet, "%NAME%", (select
name from names
where gender = "male"
) )
) as snippet
from imagedata
where timestamp is not NULL
order by random()
limit 10
I was expecting for each row of the SELECT to have different random replacement every time the subquery is invoked.
hello i'm %NAME% and this is my house
This is the car of %NAME%, let me know what you think
instead each row has the same kind of replacement:
hello i'm david and this is my house
This is the car of david, let me know what you think
and so on...
I'm not sure it can be done inside sqlite or if i have to do it in php over two different database queries.
Thanks in advance!
Seems that random() in the subquery is only evaluated once.
Try this:
select
i.id,
replace(i.snippet, '%NAME%', n.name) snippet
from (
select
id,
snippet,
abs(random()) % (select count(*) from names where gender = 'male') + 1 num
from imagedata
where timestamp is not NULL
order by random() limit 10
) i inner join (
select
n.name,
(select count(*) from names where name < n.name and gender = 'male') + 1 num
from names n
where gender = 'male'
) n on n.num = i.num
I am trying out SQLite and encountered a problem. There are 3 Tables A, B, and C.
I want to update Table A using the sum of B and C.
Table A.
James null.
Table B.
James 5.
Table C
James 2
so with the update, I want table A to have
James 3. (5-2)
Thank You
SQLite does not support joins in an UPDATE statement so you can do it by accessing directly the corresponding rows of the tables A and B like this:
update A
set value =
(select value from B where name = A.name) -
(select value from C where name = A.name)
If you want to update only the row with name = 'James' then add:
where name = 'James'
See the demo
Works in every DB:
UPDATE
"A"
SET
"x" =
(
SELECT
SUM("x")
FROM "B"
WHERE "B"."id"="A"."id"
) +
(
SELECT
SUM("x")
FROM "C"
WHERE "C"."id"="A"."id"
)
I believe the following demonstrates that Yes you can:-
DROP TABLE IF EXISTS ta;
DROP TABLE IF EXISTS tb;
DROP TABLE IF EXISTS tc;
CREATE TABLE IF NOT EXISTS ta (name TEXT, numb INTEGER);
CREATE TABLE IF NOT EXISTS tb (name TEXT, numb INTEGER);
CREATE TABLE IF NOT EXISTS tc (name TEXT, numb INTEGER);
INSERT INTO ta VALUES ('JAMES',null),('Mary',100);
INSERT INTO tb VALUES ('JAMES',5),('Sue',33);
INSERT INTO tc VALUES ('JAMES',2),('Anne',45);
UPDATE ta SET numb =
(SELECT sum(numb) FROM tb WHERE name = 'JAMES')
-
(SELECT sum(numb) FROM tc WHERE name = 'JAMES')
WHERE name = 'JAMES';
SELECT * FROM ta;
SELECT * FROM tb;
SELECT * FROM tc;
This :-
Drops the tables if they exist allowing it to be rerun (simplifies modifications if need be).
column names name and numb have been assumed as they weren't given.
Creates the 3 tables (note table names used for the demo are ta, tb and tc)
Adds some data (note that additional rows have been added to show how to distinguish (at least to a fashion))
Updates column numb of table A (ta) where the name column has a value of JAMES according to the sum of the numb column from all rows with the same name (JAMES) from table tb minus the sum of the numb column from all rows with the same name (JAMES) from table tc
This may not be exactly what you want so it assumes that you want to sum all rows with the same name per table (ta and tc)
Queries all the tables (first is shown below as that is the table that has been updated.)
The first result showing that the row has been updated from null to 3 (5 - 2) and that the row for Mary has remained as it was :-
The following change to the UPDATE gets the name (rather than hard-coding 'JAMES' multiple times, as per the row(s) extract from the ta table, the use of hard-coded names perhaps making it easier to understand the working of the SQL).
UPDATE ta SET numb = (SELECT sum(numb) FROM tb WHERE name = ta.name) - (SELECT sum(numb) FROM tc WHERE name = ta.name) WHERE name = 'JAMES';
Note that should there not be an associated row (i.e. with the same name) in either tb or tc then the result will be null (whether or not sum is used).
Table three columns id, numers1 and numbers2. We need to summarize numers1 and numbers2 but the first row to the second row numers1 numers2 the second with the third and forth etc.:
CREATE TABLE tb1 (id INTEGER PRIMARY KEY AUTOINCREMENT,numbers1,numbers2);
INSERT INTO tb1 (numbers1,numbers2) values(1,10);
INSERT INTO tb1 (numbers1,numbers2) values(2,20);
INSERT INTO tb1 (numbers1,numbers2) values(3,30);
INSERT INTO tb1 (numbers1,numbers2) values(4,40);
INSERT INTO tb1 (numbers1,numbers2) values(5,50);
I want to get as:
21
32
43
54
with the reference of getting the correct row index per record here:
How to use ROW_NUMBER in sqlite
I was able to create the required result with the following query:
SELECT
num1 + coalesce(b_num2, 0)
FROM(
SELECT
num1,
(select count(*) from test as b where a.id >= b.id) as cnt
FROM test as a) as a
LEFT JOIN
(SELECT num2 as b_num2,
(select count(*) from test as b where a.id >= b.id) as cnt
FROM test as a
) as b
ON b.cnt = a.cnt + 1
Explanation:
by joining two same table of similar record index, then merge the next record with the current record and then sum num1 of current record with num2 of next record, I do not know how you want to deal with the last row as it does not have a next row so I assume it to add nothing to have a result of just the value of num1
Result:
For one row with a specific ID x, you can get values from the next row by searching for ID values larger than x, and taking the first such row:
SELECT ...
FROM tb1
WHERE id > x
ORDER BY id
LIMIT 1;
You can then use this as a correlated subquery to get that value for each row:
SELECT numbers1 + (SELECT T2.numbers2
FROM tb1 AS T2
WHERE T2.id > T1.id
ORDER BY T2.id
LIMIT 1) AS sum
FROM tb1 AS T1
WHERE sum IS NOT NULL; -- this omits the last row, where the subquery returns NULL
I'm adding an 'index' column to a table in SQLite3 to allow the users to easily reorder the data, by renaming the old database and creating a new one in its place with the extra columns.
The problem I have is that I need to give each row a unique number in the 'index' column when I INSERT...SELECT the old values.
A search I did turned up a useful term in Oracle called ROWNUM, but SQLite3 doesn't have that. Is there something equivalent in SQLite?
You can use one of the special row names ROWID, OID or _ROWID_ to get the rowid of a column. See http://www.sqlite.org/lang_createtable.html#rowid for further details (and that the rows can be hidden by normal columns called ROWID and so on).
Many people here seems to mix up ROWNUM with ROWID. They are not the same concept and Oracle has both.
ROWID is a unique ID of a database ROW. It's almost invariant (changed during import/export but it is the same across different SQL queries).
ROWNUM is a calculated field corresponding to the row number in the query result. It's always 1 for the first row, 2 for the second, and so on. It is absolutely not linked to any table row and the same table row could have very different rownums depending of how it is queried.
Sqlite has a ROWID but no ROWNUM. The only equivalent I found is ROW_NUMBER() function (see http://www.sqlitetutorial.net/sqlite-window-functions/sqlite-row_number/).
You can achieve what you want with a query like this:
insert into new
select *, row_number() over ()
from old;
No SQLite doesn't have a direct equivalent to Oracle's ROWNUM.
If I understand your requirement correctly, you should be able to add a numbered column based on ordering of the old table this way:
create table old (col1, col2);
insert into old values
('d', 3),
('s', 3),
('d', 1),
('w', 45),
('b', 5465),
('w', 3),
('b', 23);
create table new (colPK INTEGER PRIMARY KEY AUTOINCREMENT, col1, col2);
insert into new select NULL, col1, col2 from old order by col1, col2;
The new table contains:
.headers on
.mode column
select * from new;
colPK col1 col2
---------- ---------- ----------
1 b 23
2 b 5465
3 d 1
4 d 3
5 s 3
6 w 3
7 w 45
The AUTOINCREMENT does what its name suggests: each additional row has the previous' value incremented by 1.
I believe you want to use the constrain LIMIT in SQLite.
SELECT * FROM TABLE can return thousands of records.
However, you can constrain this by adding the LIMIT keyword.
SELECT * FROM TABLE LIMIT 5;
Will return the first 5 records from the table returned in you query - if available
use this code For create Row_num 0....count_row
SELECT (SELECT COUNT(*)
FROM main AS t2
WHERE t2.col1 < t1.col1) + (SELECT COUNT(*)
FROM main AS t3
WHERE t3.col1 = t1.col1 AND t3.col1 < t1.col1) AS rowNum, * FROM Table_name t1 WHERE rowNum=0 ORDER BY t1.col1 ASC