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)
Related
I want to specify that a phone number is already existed in other table or not. If it is existed then it must show me 'yes' otherwise show me 'no'. For exanple:
Select Name, PHONE_NO, (Select 'yes' from cdr_personal_info c , tec_personal_info t where c.phone_no=t.phone_no) CDR_existence from TEC_PERSONAL_INFO;
The above query display 'yes' with all columns of TEC_PERSONAL_INFO table it should only display 'yes' with one column which is existed in CDR_PERSONAL_INFO table.
Note: these two tables does not have any kinds of relationship with each other.
You could use an exists condition around your subquery - though you don't need to refer to the driving table again - within a case expression:
select t.name,
t.phone_no,
case when exists (
select null from cdr_personal_info c where c.phone_no=t.phone_no
) then 'yes' else 'no' end as cdr_existence
from tec_personal_info t
Or you could use an outer join, but you might have to deal with duplicates if the cdrpersonal_info table can have the same phone number more than once:
select t.name,
t.phone_no,
case when c.phone_no is null then 'no' else 'yes' end as cdr_existence
from tec_personal_info t
left join cdr_personal_info c on c.phone_no=t.phone_no
db<>fiddle demo with some made-up data.
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.
I have a string that contains ID numbers, something like this: „1;3;5;6;7;“
I want to select all rows in an SQLite table that have an ID which is contained in that string.
One select statement that gives me the rows 1,3,5,6 and 7.
Any idea how to do this?
You can do it with LIKE operator:
select * from tablename
where ';' || '1;3;5;6;7' || ';' like '%;' || id || ';%'
You can use the SQLite instr core function
SELECT * FROM your_table WHERE instr(';'||'1;3;5;6;7;',';'||id||';');
preceding the list with ; and wrapping the id in ;'s ensures that only the specific values are extracted (e.g. so that 1 doesn't get 11 111 etc)
I have a table where I store "id" values of employees. Now I need write a Select from that table with concatenation of Name & Surname of that employees. This select works ok when I do concatenation from same schema:
SELECT NAME || ' ' || SURNAME "Employee"
FROM Schema1.Table1
LEFT JOIN Schema1.Table2 u
ON Manager = u.ID
ORDER BY ID.Table1;
But when I do concatenation of same kind of data (same column types and names also) from different schema, I receive "invalid number" error in "u.ID":
SELECT NAME || ' ' || SURNAME "Employee"
FROM Schema1.Table1
LEFT JOIN Schema2.Table2 u
ON Manager = u.ID
ORDER BY ID.Table1;
Why isn't same Select working in both cases, and what should 2nd Select be like ?
Thanks for help in advance !
Sorry, my bad, second schema had a Varchar2 type of something I have Number type in my schema. To_Char solved my problem:
SELECT NAME || ' ' || SURNAME "Employee"
FROM Schema1.Table1
LEFT JOIN Schema2.Table2 u
ON to_char(Manager) = u.ID
ORDER BY ID.Table1;
I am very new to Oracle 11g and am trying to generate a large string by appending text for each column in a select statement and using a cursor to store the results. However I want the last statement to not have a union all included. The final result I want to build large string of each row generated or simply execute the result if possible.
Note: column1 has a list of schemas that I am interested in.
select 'select * from ' || column1 || '.' || column2 || ' union all ' from mytable
This is where column1 is the schema, column2 is the table name.
What is the simplest way to generate the final string without using rtrim to remove the last string. And is there a simple way to append all these rows together in the string automatically?
The final goal is to actually just execute the union into a resulting cursor.
If you're querying in a loop anyway I wouldn't try to construct the string as part of the select at all; I'd do it all within the loop. Something like (untested):
declare
str varchar2(32768);
begin
for rec in (select column1, column2, rownum as rn from mytable)
loop
if rec.rn > 1 then
str := str || ' union all ';
end if;
str := str || 'select * from "' || rec.column[ || '"."' || rec.column2 ||'"';
end loop;
-- do something with str e.g. display to verify the syntax
-- before using in a cursor
dbms_output.put_line(str);
end;
Rather than adding union all to the end of every row except the last one,the rn check means it's added to the start of every row except the first one, which is easier to detect.
I've also wrapped the schema and table names in double quotes, just in case you have to deal with any quoted identifiers. But if your stored values don't match the case of the owners and table names in all_tables this will cause a problem rather than solve it.