SQLite query with - || OR. Concatenated results - sqlite

I have a problem with the following query :
SELECT DISTINCT city || strftime("%Y", begintime) FROM Texts_original1
The query itself works but results themselves are concatenated so instead of for example :
city = Dublin
strftime("%Y", begintime) = 2008
I get :
city || strftime("%Y", begintime) = Dublin2008
Any ideas how to avoid that concatenation and make the response be separated to different columns ?

The || operator is "concatenate" - it joins together the two strings of its operands. (Source)
So, whatever it is you're trying to do, the || operator isn't what you want.

change || by a comma to make it different columns. what happens if you try to execute this?
SELECT DISTINCT city, strftime("%Y", begintime)
FROM Texts_original1
you tried to mention this: how to avoid that concatenation and make the response be separated to different columns

Related

How to concatenate a Select query inside a INSTR() in SQLite?

I was trying to order a result set by the order of the values in an IN() clause.
SELECT * FROM CrossReference WHERE cross_reference_id IN (SELECT Id FROM FilteredIds)
So I tried to find a function such as MySql FIELD(). Then I found these answers (answer1, answer2) which explain how to do the exact thing on SQLite using the INSTR().
SELECT *, INSTR(',GDBR10,GDBR5,GDBR30,', ',' || ticker || ',') POS
FROM tbl
WHERE POS>0
ORDER BY POS;
So it's working as expected, but I want to populate the ids dynamically using a select query. I tried many approaches, but nothing seemed to work. Here is the last one I tried. It gave me just one result row (a result related to the first filterId).
SELECT *, INSTR (','||(SELECT id FROM FilteredIds)||',', ',' || cross_reference_id || ',') POS FROM CrossReference WHERE POS>0 ORDER BY POS;
So I guess I'm making some kind of mistake when concatenating the SELECT query with the rest of the code. Because when I manually enter the filtered Ids it works and returns results according to the entered filter ids.

Ambiguity between column alias and another column's name

I have got some tables with overlapping column names and I want to combine those columns into one column with the same name as alias, e.g.
select a.name || " " || b.name as name from a join b
This works fine. However, if I want to order them, e.g.
order by lower(name) asc
I get the error ambiguous column name: name, because sqlite doesn't know whether to use a's, b's or the selection's name column. My question is whether it is possible to specifically chose the selection's name column (without giving it a different alias)? Maybe there is some nice <keyword> such that <keyword>.name results in the selection's name column. Or is there really no better solution than
with tmp as (select tmp_a.name || " " || tmp_b.name as name from tmp_a join tmp_b)
select name from tmp order by lower(name) asc
I don't think that the use of the CTE or a subquery is not a good solution.
If you don't like them, the only way to do it is to repeat the expression in the ORDER BY clause:
select a.name || ' ' || b.name as name
from a join b
on ......
order by lower(a.name || ' ' || b.name)

How can I bulk rename table columns in a SQLite database?

I created a whole bunch of SQLite database tables. Many columns in the tables have names with spaces, which I'm now realizing was not such a brilliant idea. Is there a way to write one command which will get rid of all spaces in all columns in all tables? I know I can do it one at a time (all potential duplicates seem to address this issue rather than my issue) but it's going to take me forever. Any ideas on how I can do this?
Use the following SQL to find all of the column names that contain spaces. I also included SQL to generate a new name.
SELECT t.name as tablename, c.name as badcol, replace(c.name, ' ','_') as newcolname
FROM sqlite_master t
JOIN pragma_table_info(t.name) c
WHERE t.type = 'table' AND c.name like '% %';
From here you would have to generate alter statements looking like this:
ALTER table <tablename> RENAME COLUMN <badcol> to <newcolname>;
While I cant figure how to directly pass the list of parms to the Alter table command you can use the following SQL to generate the alter commands for you then just copy/paste the result and execute the list of them.
SELECT ('ALTER TABLE ' || t.name || ' RENAME COLUMN ' || '[' || c.name || ']'
|| ' TO ' || '[' || REPLACE(c.name, ' ','_') || '];')
FROM sqlite_master t
JOIN pragma_table_info(t.name) c
WHERE t.type = 'table' AND c.name like '% %';
In this SQL I replaced the spaces in col names with underscores but you can see where you could replace the REPLACE function with the column renaming solution you desire.

How to concat two column with '-' seperator in PL/SQL

I just want to concat two columns with seperator '-'.
These are the two columns, want to concat.
I am using this query to concat them
select concat(amt,endamt)as amount from mstcatrule
and it is giving me result this
But I Want that data of 2 columns should be sepearted by '-'
RESULT I WANT IS :
AMOUNT
0-0
100-99999999999
100-500
Alternative:
select amt || '-' || endamt as amount from mstcatrule;
Do it with two concats:
select concat(concat(amt, '-'), endamt) as amount from mstcatrule;
concat(amt,'-') concatenates the amt with the dash and the resulting string is concatenated with endamt.
Another way is to use double pipe.
select amt || '-' || endamt as amount from mstcatrule;
You may have to convert amt and endamt to varchar
In oracle this works for me! :D
select amt||'-'||endamt as amount from mstcatrule
Alternative you can use under query
select concat(amt,'-',endamt) as amount from mstcatrule;
A generic format for the query
Select concat(column1,'-',column2) as concatedCols from table_Name
For Postgresql only

SQLite full-text search with multiple tokens using a prepared statement

Given the following tables:
create table index(name text, docid int);
create virtual table docs using fts4();
The following query works as intended when querying for a single token (for example: march, or bad):
select name from index where docid in (select docid from docs where docs match ?)
But how can I query for more than one token (say, bad bed)? Binding the string bad bed directly does not work (always selects nothing), neither surrounding the placeholder or the string with double quotes, nor using AND to MATCH each token separetly (this last one throws an error).
Using intersect does work, but it's clunky and innefficient when searching for many tokens:
select name from index where docid in (
select docid from docs where docs match ?
intersect
select docid from docs where docs match ?
intersect
...
)
Each ? is paired with a single token.
You can use the concatenation operator || in sqlite. '' would be the empty string
SELECT * FROM table WHERE docs MATCH '' || ? || ' ' || ? || ' ' || ? || ''
Make sure there is a space between every token or an ' AND '.
Update
Actually it doesn't work. It seems there are tokenator issues with this approach. Its better to concatenate all the tokens with the space and bind the resulting string with a single '?'
There are operators within the match syntax in FTS so you can use AND, OR and NOT.
See here for documentation
e.g.
-- Return the docid values associated with all documents that contain the
-- two terms "sqlite" and "database", and/or contain the term "library".
SELECT docid FROM docs WHERE docs MATCH 'sqlite AND database OR library';

Resources