I have a SQL query that combines multiple results from a table into a single row, ordered list result set.
TableA
Col1
ABC
DEF
select * from TableA for xml raw(''), root('ol'), elements, type
Output:
<ol><li>ABC</li><li>DEF</li></ol>
Would like to achieve the same result in Snowflake
There's no built-in XML constructor in Snowflake, but for simple XML formats you can use listagg and concatenation to produce the XML:
create or replace temp table T1(COL1 string);
insert into T1 (COL1) values ('ABC'), ('DEF');
select '<ol><li>' || listagg(COL1, '</li><li>') || '</li></ol>' from T1;
Related
I have a select query that returns a single column. Is there a way in sqlite to create a new table using the results as column names?
I tried this but it did not work.
CREATE TABLE newTable (SELECT nameCol FROM oldTable);
SQLite does not support dynamic SQL so this is not possible.
The best that you can do is construct the SQL statement that you can use to create the table by using your preferred programming language:
SELECT 'CREATE TABLE newTable (' ||
(SELECT GROUP_CONCAT(nameCol) FROM oldTable) ||
');' AS sql;
The above query returns 1 row with 1 column with a string like:
CREATE TABLE newTable (column1,column2,column3);
See a simplified demo.
I've the input data in SQL table in below format:
ID Text
1 <Key><Name>Adobe</Name><Display>Ado</Display></Key><Key>.....</Key>
2 <Key><Name></Name><Display>Microsoft</Display><Version>1.1</Version></Key>
There can be multiple keys for each ID.There could be several thousand rows in a table in above format. I've to generate the final sql output in below format
ID Name Display Version
1 Adobe Ado
1 xyz yz 1.2
2 Microsoft 1.1
I am using the below query to parse Text column, but getting all data in one row. How can I split that data in multiple rows as indicated above.
SELECT
CAST(CAST(Text AS XML).query('data(/Key/Name)') AS VARCHAR(MAX)) AS Name,
CAST(CAST(Text AS XML).query('data(/Key/Display)') as VARCHAR(MAX)) AS DisplayName,
CAST(CAST(Text AS XML).query('data(/Key/Version)') AS VARCHAR(MAX)) AS Version
FROM
ABC where ID = 1
Currently I am running this query for each ID at a time. Is there a way to run for all ID's together. Also, is there any other efficient way to get the desired output.
Here is the example:
-- Sample demonstrational schema
declare #t table (
Id int primary key,
TextData nvarchar(max) not null
);
insert into #t
values
(1, N'<Key><Name>Adobe</Name><Display>Ado</Display></Key><Key><Name>xyz</Name><Display>yz</Display><Version>1.2</Version></Key>'),
(2, N'<Key><Name></Name><Display>Microsoft</Display><Version>1.1</Version></Key>');
-- The actual query
with cte as (
select t.Id, cast(t.TextData as xml) as [XMLData]
from #t t
)
select c.Id,
k.c.value('./Name[1]', 'varchar(max)') as [Name],
k.c.value('./Display[1]', 'varchar(max)') as [DisplayName],
k.c.value('./Version[1]', 'varchar(max)') as [Version]
from cte c
cross apply c.XMLData.nodes('/Key') k(c);
Different type can be corrected with the in-place cast/convert done in CTE (or equivalent subquery).
I want to compare two multiple value strings with each other to see if one of the values exists in the other string.
I have a table with a nvarchar row with pipe separated values, e.g.
'value1|value2|value3'
I also have an nvarchar variable with a comma separated string, e.g.
'value2,value3'
until now the column in the table had one value, I used a table function to spit the string in the variable and used the IN clause to see if the value was in the generated table. e.g.
select * from table1
WHERE column in (select val from dbo.split(#variable,','))
this won't work if the column also contains more values.
select * from table1
WHERE (select val from dbo.split(column,'|')) in (select val from dbo.split(#variable,','))
here it tries to compare 2 generated tables with each other which fails. I have tried this using joins, but can't find a way to properly do this. I'm using MSSQL 2008R2
Maybe this can help you:
select * from table1 where exists
(select * from
(select val from dbo.split(table1.column,'|')) a,
(select val from dbo.split(#variable,',')) b
where a.val=b.val)
In TSQL is there a function to select a row as normal and then as an aliased column return some of those fields in XML format.
I'm creating an error log and I'd like to insert into a table the Primary key as a standard column and then some of the fields in the table as combined xml. I'm pretty new to dealing with xml and I've found out how to return xml data but not as a aliased column of a select query.
Is this possible? I apologise if this has been answered already. I have a feeling I just don't know what the right search terms are.
Thanks!
You can use a sub-select with FOR XML to to this, something along the lines of this;
select
id,
column1,
column2,
column3,
(select
column4,
column5,
column6
from
my_table t2
where
t2.id = t1.id
for xml path, type) as columnx
from
my_table t1
this time i have question how to convert MSSQL table to XML
My source SQL table:
+-----------+-----------------+
|atributname|atributvalue |
+-----------+-----------------+
|phone |222 |
|param4 |bbbbcdsfceecc |
|param3 |bbbbcdsfceecc |
|param2 |bbbbcdsfccc |
+-----------+-----------------+
Expected result sample:
<items>
<phone>222</phone>
<prama4>bbbbcdsfceecc</param4>
<param3>bbbbcdsfceecc</param3>
<param2>bbbbcdsfccc</param2>
</items>
I tried lot of variations of the following query
SELECT atributname,atributvalue
FROM sampletable FOR XML PATH (''), ROOT ('items');
but results are not good :( should be exactly like in "Expected result sample"
any help
ps
Script to create sampletable:
create table sampletable
(atributname varchar(20),
atributvalue varchar(20))
insert into sampletable (atributname,atributvalue)
values ('phone','222');
insert into sampletable (atributname,atributvalue)
values ('param4','bbbbcdsfceecc');
insert into sampletable (atributname,atributvalue)
values ('param3','bbbbcdsfceecc');
insert into sampletable (atributname,atributvalue)
values ('param2','bbbbcdsfccc');
That's not how FOR XML works. It's columns that get turned into XML elements, not rows. In order to obtain the expected result, you would need to have columns named phone, param4, and so on - not rows with these values in attributename.
If there are specific elements you want in the XML, you could perform a pivot on the data first, then use FOR XML.
Example of a pivot would be:
SELECT [phone], [param2], [param3], [param4]
FROM
(
SELECT attributename, attributevalue
FROM attributes
) a
PIVOT
(
MAX(attributevalue)
FOR attributename IN ([phone], [param2], [param3], [param4])
) AS pvt
FOR XML ROOT('items')
Of course the aggregate will only work if attributevalue is a numeric data type. If it's a character-type column, then you'll have some trouble with the pivot, as there are no built-in string aggregates in SQL server AFAIK...
ok
finally i have done this in several ways,
but this is simplest version suitable for medium dataset
declare #item nvarchar(max)
set #item= (SELECT '<' + atributname +'>' +
cast(atributvalue as nvarchar(max)) +'</' + atributname +'>'
FROM sampletable FOR XML PATH (''), ROOT ('items'));
select replace(replace(#item,'<','<'),'>','>')