is there a way in sqlite to do the equivalent of a vlookup? I'm trying to do something like this:
Master table:
ValueA | ValueB | concatValueA&ValueB
Mapping table:
concatValueA&ValueB | mapped Value
final table:
ValueA | ValueB | concatValueA&ValueB | mapped Value
In Excel, I would just do a vlookup.
Is there a way to add the mapped value to a table in sqlite?
I tried this:
UPDATE Master Set "mapped Value" = (select mapping."mapped Value" from Master left join mapping on Master.concat = mapping.concat)
But this fills sets the mapped Value column entirely equal to the first value from the select statement, but I would like the values to be different
In the subquery, Master does not refer to the row being updated because you have introduced another instance of this table in the FROM clause.
What you want is a correlated subquery, which needs to refer to a table that is otherwise not directly part of the subquery:
UPDATE Master
SET "mapped Value" = (SELECT mapping."mapped Value"
FROM mapping
WHERE Master.concat = mapping.concat)
Related
I know that in ADX I can't update an existing row because it's an append-only system.
I want to add a specific row with a condition:
if there is no other row inside the table with the same values on certain columns.
I came up with this logic but I think this can be done much simpler:
.set-or-append target_table <|
let exists_row_count = old_table | where field1 == value1 and field2 == value2 | count()
let appended_row = case(exists_row_count == 0, <the whole record>, <empty record or null>)
appended_row
*need to mention that I get the value1, value2, and when I'm using a logic app here and I can iterate on each and every new record that I want to insert into the table, and of course, that the record is in tabular form.
You can create a Materialized View on top of your original table, and dedup by the columns you choose.
Assume the two tables reside in the same file. So the question is, other than their names, are the tables identical, i.e., same schema, same contents.
To compare the table schemas, look at the statements in the sqlite_master table:
SELECT sql FROM sqlite_master WHERE tbl_name IN ('This', 'That');
You have to ignore the table name itself in the comparison; automatic replacement is harder if you have any column names or comments that containt the table name.
To compare the contents, just use compound queries to check whether there are any rows that are not in the other table:
SELECT NOT EXISTS (SELECT * FROM This
EXCEPT
SELECT * FROM That)
AND NOT EXISTS (SELECT * FROM That
EXCEPT
SELECT * FROM This);
I believe that the following may suffice :-
/*
Compare Schema and data in tables.
t1 is the SQL for the first table (mytable) with the table name changed to a common name (table)
t2 is the SQL for the second table (mytable_copy1) with the table changed to a common name (table)
(so if t1 and t2 are equal then the schema is the same)
tablecompare is the logical result of comparing the data of each table with the other table
except matching rows so if no rows exists then NOT EXISTS will be true (1) AND the two
and the result will be 1 if both tables exactly match each other.
*/
SELECT
(t1 = t1) AND tablecompare AS test FROM
(SELECT
replace(sql,'mytable','table') AS t1, -- change the table name to a common name
replace(sql,'mytable_copy1','table') AS t2, -- change the table name to a common name
(
SELECT NOT EXISTS (SELECT * FROM mytable EXCEPT SELECT * FROM mytable_copy1)
AND NOT EXISTS (SELECT * FROM mytable_copy1 EXCEPT SELECT * FROM mytable)
) AS tablecompare
FROM sqlite_master WHERE name = 'mytable'
)
Note the tables are mytable and mytable_copy1 so these would be changed to reflect the two tables.
Perhaps less confusing (perhaps more) is this more long-winded solution :-
/*
Table Compare
t1 is the SQL for the first table (mytable) with the table name replace by table
t2 is the SQL for the second table (mytable_copy1) again table name change to table
So if t1 = t2 then the schema is identical
t1count is the number of rows in the first table
t2count is the number of rows in the second table
So if the counts are the same then the tables may be identical
unioncount is the count of the union of the two tables (not union all) so duiplicates are dropped
therefore if unioncount is the same as either of the table counts then tables are identical
NOTE!!! this assumes tables are not WITHOUT ROWID tables (would have to omit the inclusion of rowid NOT TESTED)
the inclusion of rowid could be dropped (NOT TESTED) if there is an alias of rowid.
*/
SELECT
t1 = t1 AND t1count = t2count AND t1count = unioncount AS test FROM
(SELECT
replace(sql,'mytable','table') AS t1, -- change the table name to a common name
replace(sql,'mytable_copy1','table') AS t2, -- change the table name to a common name
(SELECT count() FROM mytable) AS t1count, -- get the number of rows
(SELECT count() FROM mytable_copy1) AS t2count, -- get the number of rows
(SELECT count() AS unioncount FROM
(SELECT rowid,* FROM mytable UNION SELECT rowid,* FROM mytable_copy1)) AS unioncount
FROM sqlite_master WHERE name = 'mytable'
) ;
Both solutions return a single row/column result 1 if the tables match 0 if they do not.
It could however, but less time consuming/resource hungry to do individual tests. e.g. if the schema's don't match do nothing otherwise check the row counts and if they don't match don't do the final check of actually checking the data.
Test the following tables were used for testing :-
For mytable and mytable_copy1 :-
The above both produced 1 as per :-
and :-
When the following table (mytable_copy2 with changed data highlighted) :-
The results were :-
and :-
I have the following columns in a SQLite DB.
id,ts,origin,product,bid,ask,nextts
1,2016-10-18 20:20:54.733,SourceA,Dow,1.09812,1.0982,
2,2016-10-18 20:20:55.093,SourceB,Oil,7010.5,7011.5,
3,2016-10-18 20:20:55.149,SourceA,Dow,18159.0,18161.0,
How can I populate the 'next timestamp' column (nextts) with the next timestamp for the same product (ts), from the same source? I've been trying the following, but I can't seem to put a subquery in an UPDATE statement.
UPDATE TEST a SET nextts = (select ts
from TEST b
where b.id> a.id and a.origin = b.origin and a.product = b.product
order by id asc limit 1);
If I call this, I can display it, but I haven't found a way of updating the value yet.
select a.*,
(select ts
from TEST b
where b.id> a.id and a.origin = b.origin and a.product = b.product
order by id asc limit 1) as nextts
from TEST a
order by origin, a.id;
The problem is that you're using table alias for table in UPDATE statement, which is not allowed. You can skip alias from there and use unaliased (but table-name prefixed) reference to its columns (while keeping aliased references for the SELECT), like this:
UPDATE TEST
SET nextts = (
SELECT b.ts
FROM TEST b
WHERE b.id > TEST.id AND
TEST.origin = b.origin AND
TEST.product = b.product
ORDER BY b.id ASC
LIMIT 1
);
Prefixing unaliased column references with the table name is necessary for SQLite to identify that you're referencing to unaliased table. Otherwise the id column whould be understood as the id from the closest[*] possible data source, in which case it's the aliased table (as b alias), while we're interested in the unaliased table, therefore we need to explicitly tell SQLite that.
[*] Closest data source is the one listed in the same query, or parent query, or parent's parent query, etc. SQLite is looking for the first data source (going from inner part to the outside) in the query hierarchy that defines this column.
Using SQLite, I am trying to update three columns based on another table (two columns)
The three columns are (Table1):
'AgentCreatedID'
'AgentOwnedID'
'AgentSentID'
The other table (Table2) consists of 'AgentID' and 'Designation'.
If the ID in one of the three columns matches the 'AgentID' in the second table, I want the 'Designation' value to populate. This table is a list of ALL unique IDs and the corresponding designation. Each row of data has a Creator, Owner, and Sender. I need to see what designation that person is from.
In Access, this would look something like this for the first value. I would also need to add the other two values.
UPDATE Table1
LEFT JOIN Table2 ON Table1.AgentCreatedID = Table2.AgentID
SET raw.AgentCreatedID = [ Table2 ]![ Designation];
I am not sure what that ! command is or how it could be used in SQLite.
SQLite does not suport joins in an UPDATE statement.
You have to look up the new value with correlated subqueries:
UPDATE Table1
SET AgentCreatedID = (SELECT Designation
FROM Table2
WHERE AgentID = AgentCreatedID),
AgentOwnedID = (SELECT Designation
FROM Table2
WHERE AgentID = AgentOwnedID),
AgentSentID = (SELECT Designation
FROM Table2
WHERE AgentID = AgentSentID)
The exclamation mark is used to separate the worksheet name from the reference in that worksheet. Here is Microsoft's explanation of cell references.
Now that you know what [ Table2 ]![Designatio] means, you can simplify it to use only the column name.
The question probably is quite confusing.
In affect i have the following:
WatchList table
UserId | FilmId
| 3 77
| etc etc
|
|
|
these are foreign keys for the following tables
FilmDB - Film_title, Film_plot, Film_Id etc.
and
aspnet_memberships - UserId, Username etc..
Now, i presume i will need to use a join but i am struggling with the syntax.
I would like to use 'Count' on the 'WatchList' and return the most frequent filmId's and their counterpart information, but i'd then like to return the REST of the FilmDB results, essentially giving me a list of ALL films, but with those found in the WatchedList my frequently sorted to the top.
Does that make sense? Thanks.
SELECT *
FROM filmdb
LEFT JOIN (
SELECT filmid, count(*) AS cnt
FROM watch_list
GROUP BY filmid) AS a
ON filmdb.film_id = a.filmid
ORDER BY isnull(cnt, 0) DESC;
http://sqlfiddle.com/#!3/46b16/10
You did not specify if the query should be grouped by film_id or user_id. The example I have provided is grouped by user if you change that to film_id then you will get the watch count for all users per film.
You need to use a subquery to get the count and then order the results by the count descending to get an ordered list.
SELECT
*
FROM
(
SELECT
WatchList.Film_Id,
WatchCount=COUNT(*)
FilmDB.Film_Title
FROM
WatchList
INNER JOIN FilmDB ON FilmDB.Film_Id=WatchList.Film_Id
GROUP BY
WatchList.UserID,
WatchList.Film_Id,
FilmDB.Film_Title
)AS X
ORDER BY
WatchCount DESC