I have a query that outputs just one row of data. I want to convert that row to column and the column to row.
My original query
------------------------
ID Name Desc
------------------------
1 Nisha Some desc
what I need
--------------------------
FieldName FieldValue
--------------------------
ID 1
Name Nisha
Description Some Desc
declare #colNum int, #i int = 1, #a nvarchar(4000)
select #colNum=count(COLUMN_NAME) from INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'YourTable'
set #a = '
declare #tempTable table
(
slno int
,field nvarchar(100)
,value nvarchar(100)
)
insert into #tempTable (slno,field)
select ROW_NUMBER() over (order by ordinal_position asc),COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = ''YourTable''
declare #p nvarchar(100)
'
declare #colname nvarchar(100)
while #i<=#colNum
begin
select #colname =a.COLUMN_NAME from (select COLUMN_NAME,ORDINAL_POSITION
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'YourTable'
)as a
where a.ORDINAL_POSITION = #i
set #a = #a + '
select #p='+#colname+' from YourTable
update #tempTable set
value = #p
where slno = '+CONVERT(nvarchar(5), #i)
+'
'
set #i=#i+1
end
set #a = #a + ' select * from #tempTable'
declare #tempTable table
(
slno int
,field nvarchar(100)
,value nvarchar(100)
)
insert into #tempTable exec (#a)
select * from YourTable
select * from #tempTable
Related
I want to run a query that shows me all columns from all tables in a database with the datatype varchar and a maximum length of 8000 characters.
This is my code so far.
DECLARE #tabs VARCHAR(MAX);
SET #tabs =
(
SELECT STUFF(( SELECT DISTINCT ',' + [TABLE_NAME]
FROM [DB-Test].INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE = 'VARCHAR' AND
CHARACTER_MAXIMUM_LENGTH = 8000
FOR XML PATH('')), 1, 1, '')
);
DECLARE #cols VARCHAR(MAX)
SET #cols =
(
SELECT STUFF(( SELECT DISTINCT ',' + [TABLE_NAME] + '.' + [COLUMN_NAME]
FROM [DB-Test].INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE = 'VARCHAR' AND
CHARACTER_MAXIMUM_LENGTH = 8000
FOR XML PATH('')), 1, 1, '')
);
DECLARE #query VARCHAR(MAX) = 'SELECT ' + #cols + ' FROM ' + #tabs
EXEC sp_sqlexec #query
When I run the query I get all the column names, but not the values in the columns. It's empty. No 'NULL'-values. As if #cols is interpreted as simple string maybe.
Why?
(When I read out #cols and #tabs they are correct.)
I guess there is one table available in your database which have column with VARCHAR datatype and 8000 length but that table don't have any records. Try by including only those column and table which have at least one record available.
You can try below. Check it and let me know if it works.
DECLARE #tabs VARCHAR(MAX) = ''
; WITH CTE AS
(
SELECT DISTINCT TA.NAME TABLENAME
, SUM(PA.ROWS) OVER (PARTITION BY TA.NAME ) NOOFROW
FROM SYS.TABLES TA
INNER JOIN SYS.PARTITIONS PA ON PA.OBJECT_ID = TA.OBJECT_ID
INNER JOIN SYS.SCHEMAS SC ON TA.SCHEMA_ID = SC.SCHEMA_ID
WHERE TA.IS_MS_SHIPPED = 0 AND PA.INDEX_ID IN (1,0)
), TABLENAME AS
(
SELECT ITBL.[TABLE_NAME]
FROM INFORMATION_SCHEMA.COLUMNS ITBL
WHERE ITBL.DATA_TYPE = 'VARCHAR' AND
ITBL.CHARACTER_MAXIMUM_LENGTH = 8000
AND EXISTS(SELECT 1 FROM CTE WHERE CTE.TABLENAME = ITBL.TABLE_NAME AND CTE.NOOFROW > 0) -- To check no of record available in table
)
SELECT #tabs = #tabs+ISNULL(','+TABLE_NAME, '')
FROM TABLENAME
DECLARE #cols VARCHAR(MAX) = '';
; WITH CTE AS
(
SELECT DISTINCT TA.NAME TABLENAME
, SUM(PA.ROWS) OVER (PARTITION BY TA.NAME ) NOOFROW
FROM SYS.TABLES TA
INNER JOIN SYS.PARTITIONS PA ON PA.OBJECT_ID = TA.OBJECT_ID
INNER JOIN SYS.SCHEMAS SC ON TA.SCHEMA_ID = SC.SCHEMA_ID
WHERE TA.IS_MS_SHIPPED = 0 AND PA.INDEX_ID IN (1,0)
), TABLENAME AS
(
SELECT ITBL.[TABLE_NAME], ITBL.[COLUMN_NAME]
FROM INFORMATION_SCHEMA.COLUMNS ITBL
WHERE ITBL.DATA_TYPE = 'VARCHAR' AND
ITBL.CHARACTER_MAXIMUM_LENGTH = 8000
AND EXISTS(SELECT 1 FROM CTE WHERE CTE.TABLENAME = ITBL.TABLE_NAME AND CTE.NOOFROW > 0) -- To check no of record available in table
)
SELECT #cols = #cols+ISNULL(','+[TABLE_NAME]+'.'+[COLUMN_NAME], '')
FROM TABLENAME
IF LEN(#cols) > 0 AND LEN(#tabs) > 0
BEGIN
DECLARE #query VARCHAR(MAX) = 'SELECT ' + STUFF(#cols,1,1,'') + ' FROM ' + STUFF(#tabs,1,1, '')
EXEC sp_sqlexec #query
END
ELSE
BEGIN
PRINT 'No Column available with data where it''s datatype is VARCHAR and length is 8000'
END
I want to split the two columns into two rows in a single table separated by ‘;’ in Sql Server 2008. Please help me to resolve to solve this.
Columns like:
1;2;3;4;5;6;7; and a;b;c;d;e;f;g;
Output Rows like:
1 a
2 b
3 c
4 d
5 e
6 f
7 g
First you are going to need a split function as such :
CREATE function [dbo].[Split]
(
#string nvarchar(max),
#delimiter nvarchar(20)
)
returns #table table
(
[Value] nvarchar(max)
)
begin
declare #nextString nvarchar(max)
declare #pos int, #nextPos int
set #nextString = ''
set #string = #string + #delimiter
set #pos = charindex(#delimiter, #string)
set #nextPos = 1
while (#pos <> 0)
begin
set #nextString = substring(#string, 1, #pos - 1)
insert into #table
(
[Value]
)
values
(
#nextString
)
set #string = substring(#string, #pos + len(#delimiter), len(#string))
set #nextPos = #pos
set #pos = charindex(#delimiter, #string)
end
return
end
Then using this code :
SELECT col1.Value as val1,
col2.Value as val2
FROM
(SELECT Value,
ROW_NUMBER() over(order by value asc) as rownum
FROM (
VALUES('1;2;3;4;5;6;7')
) valued(X) CROSS APPLY
DBO.SPLIT(X,';') AS SPLITEDCOL ) as col1 INNER JOIN
(SELECT Value,
ROW_NUMBER() over(order by value asc) as rownum
FROM (
VALUES('A;B;C;D;E;F;G')
) valued1(X) CROSS APPLY
DBO.SPLIT(X,';') AS SPLITEDCOL ) as col2
ON COL1.rownum = col2.rownum
if your two columns are from a table you can select them as such :
SELECT Value,
ROW_NUMBER() over(order by value asc) as rownum
FROM YourTable CROSS APPLY
DBO.SPLIT(YourColumnName,';') AS SPLITEDCOL
Note that 1 subset using cross apply is necessary for each column you want to return in rows
Hope this helps
Declare #ID as Varchar(1000)
set #ID = '1;2;3;4;5;6;7;'
SELECT
LTRIM(RTRIM(m.n.value('.[1]','varchar(8000)'))) AS ID
FROM
(
SELECT CAST('<XMLRoot><RowData>' + REPLACE(#ID,';','</RowData><RowData>') + '</RowData></XMLRoot>' AS XML) AS x
)t
CROSS APPLY x.nodes('/XMLRoot/RowData')m(n)
DECLARE #Table1 TABLE(ID INT, Value char)
INSERT INTO #Table1 VALUES (1,'a'),(1,'b'),(1,'c'),(1,'d')
SELECT STUFF((SELECT '; ' + CAST(ID AS VARCHAR(10)) [text()]
FROM #Table1
WHERE ID = t.ID
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') ID
,STUFF((SELECT '; ' + CAST(Value AS VARCHAR(10)) [text()]
FROM #Table1
WHERE ID = t.ID
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') value
FROM #Table1 t
when i run this function
CREATE PROCEDURE alege()
BEGIN
declare v_prenumeNou VARCHAR(15);
declare v_numeRandom INTEGER(10);
declare v_prenumeRandom INTEGER(10);
declare v_idCutremurRandom INTEGER(10);
set v_numeRandom = 1 + CEIL ( RAND() * 50 );
set v_prenumeRandom = 1 + CEIL ( RAND() * 50 );
set v_idCutremurRandom = 1 + CEIL ( RAND() * 50 );
select prenume into v_prenumeNou from (SELECT prenume, rownum as v_rn from voluntari) where v_rn=v_prenumeRandom;
select nume into v_numeNou from (SELECT nume, rownum as v_rn from voluntari) where v_rn=v_numeRandom;
v_idPersoanaNou := v_idPersoanaNou + 1;
INSERT INTO voluntari (IDCUTREMUR, IDPERSOANA, NUME, PRENUME)
VALUES (CONCAT('C',IFNULL(v_idCutremurRandom, '')), CONCAT('V',IFNULL(v_idPersoanaNou, '')) , v_numeNou, v_prenumeNou);
END;
i have this error
[Err] 1248 - Every derived table must have its own alias
how can i solve this ?
You must add an alias to each subquery in your select into statements:
select prenume
into v_prenumeNou
from (SELECT prenume, rownum as v_rn
from voluntari) t1 <-----------
where v_rn=v_prenumeRandom;
select nume
into v_numeNou
from (SELECT nume, rownum as v_rn
from voluntari) t1 <------------
where v_rn=v_numeRandom;
Try with this, just changed the alias of the from clauses (every deribed table must have an alias):
CREATE PROCEDURE alege()
BEGIN
declare v_prenumeNou VARCHAR(15);
declare v_numeRandom INTEGER(10);
declare v_prenumeRandom INTEGER(10);
declare v_idCutremurRandom INTEGER(10);
set v_numeRandom = 1 + CEIL ( RAND() * 50 );
set v_prenumeRandom = 1 + CEIL ( RAND() * 50 );
set v_idCutremurRandom = 1 + CEIL ( RAND() * 50 );
select prenume into v_prenumeNou from (SELECT prenume, rownum as v_rn from voluntari) AS A where v_rn=v_prenumeRandom;
select nume into v_numeNou from (SELECT nume, rownum as v_rn from voluntari) AS B where v_rn=v_numeRandom;
v_idPersoanaNou := v_idPersoanaNou + 1;
INSERT INTO voluntari (IDCUTREMUR, IDPERSOANA, NUME, PRENUME)
VALUES (CONCAT('C',IFNULL(v_idCutremurRandom, '')), CONCAT('V',IFNULL(v_idPersoanaNou, '')) , v_numeNou, v_prenumeNou);
END;
How do I accomplish my goal without using temp table or variable?
Table:
ID ModelNum Qty
123 ABC 4
123 DEF 4
Expected Result:
ID Models Qty
123 ABC | DEF 4
Thanks in advance!
DECLARE #T TABLE (ID INT,ModelNum CHAR(3),Qty INT)
INSERT INTO #T
VALUES
(123,'ABC',4),
(123,'DEF',4),
(123,'GLK',4)
SELECT DISTINCT ID, STUFF(C.List, 1, 2, '') Models, Qty
FROM #T t
CROSS APPLY (
SELECT '| ' + ModelNum
FROM #T
WHERE ID = t.ID
FOR XML PATH('')
)C(List)
Result Set
ID Models Qty
123 ABC| DEF| GLK 4
Hi how about this Query below:
I have did the same example with some different logic and different attribute.
I can get the expected OP, please response if you have any suggestions for me on btechit#hotmail.com.
Declare:
#ConcatTable table (Ename varchar(30), Empno int)
Insert into #ConcatTable values ('Steve', 100),('mathew', 100),('jon', 101),('tom', 101)
--select * from #ConcatTable
--select ROW_NUMBER()over(order by Empno)Row2,* from
--(select distinct Empno from #ConcatTable)C
declare #p varchar(100) = ''
select #p = #p+ ' '+Ename from (
select DENSE_RANK()over(order by Empno)as dens, * from #ConcatTable )A
where A.dens = 1
declare #q varchar(100) = ''
select #q = #q+ ' '+Ename from (
select DENSE_RANK()over(order by Empno)as dens, * from #ConcatTable )A
where A.dens = 2
--SELECT #p
--SELECT #q
declare #M table (Name varchar(30))
insert into #M
select * from(
select #p as v
union all
select #q as vv
)G
--SELECT ROW_NUMBER()over (order by Name desc)Rown1,* from #M
SELECT A.Name,CC.Empno FROM(
SELECT ROW_NUMBER()over (order by Name desc)Rown1,* FROM #M)A
inner join
(select ROW_NUMBER()over(order by Empno)Row2,* from
(select distinct Empno from #ConcatTable)C
)CC
on A.Rown1 = CC.Row2
Here is my sql query.
CREATE FUNCTION UF_GetOrderProducts
(
#OrderId int
)
RETURNS VARCHAR(500)
AS
BEGIN
SELECT Identity(int,1,1) ID, ProductId INTO #Temp FROM OrderProduct WHERE OrderId = #OrderId
Declare #Id int,
#Count int,
#LoopCount int,
#ProductList VARCHAR(500),
#ProductListTemp VARCHAR(500)
SET #Count = (Select Count(*) From #Temp)
SET #LoopCount = 1
SET #ProductList = ''
WHILE #LoopCount <= #Count
BEGIN
SET #ProductListTemp =( SELECT Name FROM Product WHERE ProductId =(Select ProductId from #Temp Where ID = #LoopCount))
SET #ProductList +=#ProductListTemp + '<br/>'
Set #LoopCount=#LoopCount + 1
END
DROP TABLE #Temp
RETURN #ProductList
END
GO
I have to loop in #Temp Table. Do you have any other suggestions?
Instead of temp table you can use a table variable.
declare #Temp TABLE (ID int identity, ProductId int)
insert into #Temp(ProductId)
select ProductId
from OrderProduct
where OrderId = #OrderId
But you could rewrite your function without a loop.
Something like this should do what you want.
create function IF_GetOrderProducts
(
#OrderId int
)
returns varchar(500)
as
begin
return
(
select Name+'<br/>'
from Product as P
inner join OrderProduct as OP
on P.ProductId = OP.ProductId
where OP.OrderId = #OrderId
for xml path(''), type
).value('.', 'varchar(500)')
end