Combine Query Result into single row - sql

I have sql query that result data like this one
Name | City
-------------------
Frank | London
Sebastian | New York
I want to merge that result into a single row and column like this one
Frank;London;Sebastian;New York
How do I resolve this query problem? Thanks before

By default SSMS prints results in grid format. One of the options is to print the results to text. Click this button on the menu or press the shortcut "CTRL+T". This will print tab delimited results by default, instead of the semicolon delimited results that you want. This can be changed from the Query->Query Options->Results-> Text->Output Format menu or by using "CTRL+H" in a text editor (like Notepad) to find and replace all tabs with semicolons.

You can do :
select stuff ( (select distinct ';'+t1.col2
from table t cross apply
( values (name), (city) ) t1 (col2)
for xml path ('')
), 1, 1, ''
) ;

May be this one for Oracle?
WITH tmp AS
(
SELECT 'Frank' Name, 'London' City FROM dual
UNION
SELECT 'Sebastian', 'New York' FROM dual
)
SELECT LISTAGG(name||';'||city, '; ') WITHIN GROUP(ORDER BY null) FROM tmp

In SQL Server that should do the work:
SELECT ';'+rtrim(Name)+';'+rtrim(City)
FROM Table
FOR XML PATH('')
in oracle you don't have XML PATH('') syntax but you can concatenate a field like that for example:
SELECT ';' || WM_CONCAT(name||';'||City) AS Result
FROM table
Note that in Oracle 12c WM_CONCAT is deprecated but you can use ListaAgg
SELECT LISTAGG(Name||City,';') WITHIN GROUP(ORDER BY aColumn DESC) FROM TABLE
cheers

Related

SQL Query to select a specific part of the values in a column

I have a table in a database and one of the columns of the table is of the format AAA-BBBBBBB-CCCCCCC(in the table below column Id) where A, B and C are all numbers (0-9). I want to write a SELECT query such that for this column I only want the values in the format BBBBBBB-CCCCCCC. I am new to SQL so not sure how to do this. I tried using SPLIT_PART on - but not sure how to join the second and third parts.
Table -
Id
Name
Age
123-4567890-1234567
First Name
199
456-7890123-4567890
Hulkamania
200
So when the query is written the output should be like
Output
4567890-1234567
7890123-4567890
As mentioned in the request comments, you should not store a combined number, when you are interested in its parts. Store the parts in separate columns instead.
However, as the format is fixed 'AAA-BBBBBBB-CCCCCCC', it is very easy to get the substring you are interested in. Just take the string from the fifth position on:
select substr(col, 5) from mytable;
You can select the right part of a column starting at the 4th character
SELECT RIGHT(Id, LEN(Id)-4) AS TrimmedId;
Another option using regexp_substr
with x ( c1,c2,c3 ) as
(
select '123-4567890-1234567', 'First Name' , 199 from dual union all
select '456-7890123-4567890', 'Hulkamania' , 200 from dual
)
select regexp_substr(c1,'[^-]+',1,2)||'-'||regexp_substr(c1,'[^-]+',1,3) as result from x ;
Demo
SQL> with x ( c1,c2,c3 ) as
(
select '123-4567890-1234567', 'First Name' , 199 from dual union all
select '456-7890123-4567890', 'Hulkamania' , 200 from dual
)
select regexp_substr(c1,'[^-]+',1,2)||'-'||regexp_substr(c1,'[^-]+',1,3) as result from x ; 2 3 4 5 6
RESULT
--------------------------------------------------------------------------------
4567890-1234567
7890123-4567890
SQL>

Append values from 2 different columns in SQL

I have the following table
I need to get the following output as "SVGFRAMXPOSLSVG" from the 2 columns.
Is it possible to get this appended values from 2 columns
Please try this.
SELECT STUFF((
SELECT '' + DEPART_AIRPORT_CODE + ARRIVE_AIRPORT_CODE
FROM #tblName
FOR XML PATH('')
), 1, 0, '')
For Example:-
Declare #tbl Table(
id INT ,
DEPART_AIRPORT_CODE Varchar(50),
ARRIVE_AIRPORT_CODE Varchar(50),
value varchar(50)
)
INSERT INTO #tbl VALUES(1,'g1','g2',NULL)
INSERT INTO #tbl VALUES(2,'g2','g3',NULL)
INSERT INTO #tbl VALUES(3,'g3','g1',NULL)
SELECT STUFF((
SELECT '' + DEPART_AIRPORT_CODE + ARRIVE_AIRPORT_CODE
FROM #tbl
FOR XML PATH('')
), 1, 0, '')
Summary
Use Analytic functions and listagg to get the job done.
Detail
Create two lists of code_id and code values. Match the code_id values for the same airport codes (passengers depart from the same airport they just arrived at). Using lag and lead to grab values from other rows. NULLs will exist for code_id at the start and end of the itinerary. Default the first NULL to 0, and the last NULL to be the previous code_id plus 1. A list of codes will be produced, with a matching index. Merge the lists together and remove duplicates by using a union. Finally use listagg with no delimiter to aggregate the rows onto a string value.
with codes as
(
select
nvl(lag(t1.id) over (order by t1.id),0) as code_id,
t1.depart_airport_code as code
from table1 t1
union
select
nvl(lead(t1.id) over (order by t1.id)-1,lag(t1.id) over (order by t1.id)+1) as code_id,
t1.arrive_airport_code as code
from table1 t1
)
select
listagg(c.code,'') WITHIN GROUP (ORDER BY c.code_id) as result
from codes c;
Note: This solution does rely on an integer id field being available. Otherwise the analytic functions wouldn't have a column to sort by. If id doesn't exist, then you would need to manufacture one based on another column, such as a timestamp or another identifier that ensures the rows are in the correct order.
Use row_number() over (order by myorderedidentifier) as id in a subquery or view to achieve this. Don't use rownum. It could give you unpredictable results. Without an ORDER BY clause, there is no guarantee that the same query will return the same results each time.
Output
| RESULT |
|-----------------|
| SVGFRAMXPOSLSVG |

Increase every character in particular column to next characters - hive

I am working on hive. I want to decode all records in name column by increasing every character to count 3. Example if name is abc i want cde. How can I do this using hive?
EDIT : A much simpler solution : with TRANSLATE function.
SELECT TRANSLATE (name,
'abcdefghijklmnopqrstuvwxyz',
'defghijklmnopqrstuvwxyzabc')
FROM yourtable;
OLD Approach (Don't use )
You could use a combination of splitting, converting to ascii, adding reconverting and joining them back into a string.
WITH t AS
( SELECT 'abc' AS name
UNION ALL
SELECT 'pqr' AS name
) ,
ASC AS
(SELECT name,
ASCII(t1.letter) ascii_number
FROM t LATERAL VIEW explode(split( REGEXP_REPLACE(name,'(.)' , '$1|') , '\\|') ) t1 AS letter
)
SELECT name,
concat_ws('',collect_set( DECODE(unhex(hex(ascii_number+3)), 'US-ASCII') ) ) as name_plus_3
FROM ASC
GROUP BY name;
O/p:
name name_plus_3
---- ----------
abc def
pqr stu

Search from comma separated values

I have user tables which contains column city_id and inside this column city ids are stored as comma separated values as following:
User
user_id user_name city_id
1 ahmar_arshad 1,2,3
2 abdul_muiz 15,2,9
3 abdul_momin 1,2,13
Now I want to search rows which contains city id = 1 from city_id column.
How it can be done?
Here is a general solution, which should work on Postgres:
SELECT *
FROM yourTable
WHERE ',' || city_id || ',' LIKE '%,1,%';
Demo
The trick here is to compare the CSV list of city IDs in the form, e.g. ,1,2,3, against ,ID,, where ID can be any individual city ID.
Note that it would be best to normalize your table and store those city IDs across separate records instead of in CSV strings. This would make querying your data easier, and would probably also increase performance.
If you convert that comma separated list to an array you can use Postgres' powerful array operators:
select *
from cities
where '1' = any (string_to_array(city_id, ','));
If you need to find rows with on of several ID's
select *
from cities
where string_to_array(city_id, ',') && array['1', '2']
The && is the "overlaps" operator for arrays. If you need to find rows that contain all of a list of IDs: you can use the contains operator:
select *
from cities
where string_to_array(city_id, ',') #> array['1', '2']
Check This.
you should use string_to_array to spilt column and then use city_id='1' conditon in where clause.
select * from (
select id,user_name,unnest(string_to_array(city_id, ',')) city_id
from RT
)a where city_id='1'
Check Demo Here.
OutPut
Try this query !
SELECT *
FROM [Table Name]
WHERE city_id LIKE '1,%,%'
OR city_id LIKE '%,1,%'
OR city_id LIKE '%,%,1';
Try this One..
--**********************************************************************************
--Creating Table structure for the reference
create table #test (user_id int,user_name varchar(100),city_id varchar(25))
insert into #test values (1,'ahmar_arshad','1,2,3')
insert into #test values (1,'abdul_muiz','15,2,9')
insert into #test values (1,'abdul_momin','1,2,13')
--select * from #test
--**********************************************************************************
-- Query
select user_id,user_name,city_id from
(
select user_id,user_name,city_id,replace(city_id,',','') as City_ID2
from #test
)A
where City_ID2 like '%1%'
-- Replace comma with star(*) and then search.
--**********************************************************************************
SELECT *
FROM user
WHERE user_id LIKE '%1%';
you can search like keyword on w3school

SQL Server: how to compare two tables

I have problem with comparing two tables in SQL Server.
I have first table [Table1] with text column where I store my content and second table [table2] with column of my keywords.
And now I want to compare all my keywords against my content and get a list of keywords with number of occurrences in the content. (clear enough?)
What version of SQL Server? If SQL2008 you can do (probably after casting from text to nvarchar(max))
WITH Table1 AS
(
SELECT 1 AS Id, N'how now brown cow' AS txt UNION ALL
SELECT 2, N'she sells sea shells upon the sea shore' UNION ALL
SELECT 3, N'red lorry yellow lorry' UNION ALL
SELECT 4, N'the quick brown fox jumped over the lazy dog'
),
Table2 AS
(
SELECT 'lorry' as keyword UNION ALL
SELECT 'yellow' as keyword UNION ALL
SELECT 'brown' as keyword
)
SELECT Table1.id,display_term, COUNT(*) As Cnt
FROM Table1
CROSS APPLY sys.dm_fts_parser('"' + REPLACE(txt,'"','""') + '"', 1033, 0,0)
JOIN Table2 t2 ON t2.keyword=display_term
WHERE TXT IS NOT NULL
GROUP BY Table1.id,display_term
ORDER BY Cnt DESC
Returns
id display_term Cnt
----------- ------------------------------ -----------
3 lorry 2
3 yellow 1
4 brown 1
1 brown 1
This would return you list of IDs from Table1 (id int, txt ntext) with key woards from Table2 (kwd nvarchar(255)) that exist in ntext field. Number of occurrences is tricky and you will have to write UDF, preferable CLR one, to get it.
I defined word as everything that is separated by space or open parenthesize from left and space, close parenhesize, comma, dot or semicolon from right. You can add more conditions eg quotes, double-quotes etc.
Select Table1.id, Table2.kwd
From Table1
Cross Join Table2
Where patindex(N'%[ (]'+Table2.kwd+N'[ ,.;)]%',N' '+cast(Table1.txt as nvarchar(max))+N' ')>0
Order by id, kwd