I am trying to marge two rows and making single column. same data of row has to marge, and different data has to append to same row,
example:
I got result from joining three tables like this
uid name diseaseid intensity
1 xxxx 1 high
1 xxxx 2 low
Now I need final result like this
uid name diseaseid1 intensity diseaseid2 intensity
1 xxxx 1 high 2 low
Is there any option to make like this in Sql please help me out.
Thanks in advance.
Try this
CREATE TABLE #Table1
([uid] int, [name] varchar(4), [diseaseid] int, [intensity] varchar(4))
;
INSERT INTO #Table1
([uid], [name], [diseaseid], [intensity])
VALUES
(1, 'xxxx', 1, 'high'),
(1, 'xxxx', 2, 'low')
;
SELECT MAX([uid]) AS [uid]
,MAX([name]) AS [name]
,MAX([diseaseid1]) AS [diseaseid1]
,MAX([intensity1]) AS [intensity1]
,MAX([diseaseid2]) AS [diseaseid2]
,MAX([intensity2]) [intensity2]
FROM
(
SELECT [uid], [name]
, CASE WHEN rn=2 THEN NULL ELSE [diseaseid] END AS [diseaseid1]
, CASE WHEN rn=2 THEN NULL ELSE [intensity] END AS [intensity1]
, CASE WHEN rn=1 THEN NULL ELSE [diseaseid] END AS [diseaseid2]
, CASE WHEN rn=1 THEN NULL ELSE [intensity] END AS [intensity2]
FROM
(
SELECT [uid], [name], [diseaseid], [intensity],
ROW_NUMBER() OVER(PARTITION BY [uid] ORDER BY Name) AS rn
FROM #Table1
) T
) T
GROUP BY [uid], [name]
DROP TABLE #Table1
EIDT
Try this for dynamic columns
CREATE TABLE #Table1
([uid] int, [name] varchar(10), [diseaseid] int, [intensity] varchar(10))
INSERT INTO #Table1
([uid], [name], [diseaseid], [intensity])
VALUES
(1, 'xxxx', 1, 'high'),
(1, 'xxxx', 2, 'low'),
(1, 'xxxx', 3, 'medium')
DECLARE #MaxRows INT
DECLARE #CurrentRow INT
DECLARE #Query VARCHAR(MAX)
SET #CurrentRow = 1
SELECT #MaxRows = MAX(cnt) FROM (
SELECT COUNT(name) cnt FROM #Table1 GROUP BY [uid]
) AS T
SET #Query = '
SELECT MAX([uid]) AS [uid]
,MAX([name]) AS [name]'
WHILE #CurrentRow <= #MaxRows
BEGIN
SET #Query= #Query + '
,MAX(diseaseid'+CONVERT(VARCHAR(10),#CurrentRow)+') AS diseaseid'+CONVERT(VARCHAR(10),#CurrentRow)+''
SET #Query= #Query + '
,MAX(intensity'+CONVERT(VARCHAR(10),#CurrentRow)+') AS intensity'+CONVERT(VARCHAR(10),#CurrentRow)+''
SET #CurrentRow = #CurrentRow + 1
END
SET #Query= #Query + ' FROM
(
SELECT [uid], [name]'
SET #CurrentRow = 1
WHILE #CurrentRow <= #MaxRows
BEGIN
SET #Query= #Query + '
, CASE WHEN rn='+CONVERT(VARCHAR(10),#CurrentRow)+' THEN [diseaseid] ELSE NULL END AS diseaseid'+CONVERT(VARCHAR(10),#CurrentRow)+''
SET #Query= #Query + '
, CASE WHEN rn='+CONVERT(VARCHAR(10),#CurrentRow)+' THEN [intensity] ELSE NULL END AS intensity'+CONVERT(VARCHAR(10),#CurrentRow)+''
SET #CurrentRow = #CurrentRow + 1
END
SET #Query= #Query + ' FROM
(
SELECT [uid], [name], [diseaseid], [intensity],
ROW_NUMBER() OVER(PARTITION BY [uid] ORDER BY Name) AS rn
FROM #Table1
) T2
) T3
GROUP BY [uid], [name]'
PRINT (#Query)
EXEC (#Query)
DROP TABLE #Table1
You can use a query like this one
select *,(select col1,col2 from table2 where uid=t.uid) from table1 t
i think u're doing your joins wrong...
It looks like u're doing a Union of u're only grouping by UID, name.
Without knowing the join, the best advice i can give u is to try experiment with Right and Left outer join.
I think this should do what u want.
Try joining the table u get from the diseaseid twice, once with join and the second time with right outer join, this way u should get the diseaseid2 without problems.
Related
How can I select information from tables from many bases in one result. My idea is to put them in DataTable and show them in DataGrid.
Here is query:
exec sp_msforeachdb 'use ?; IF ''?'' <> ''master'' AND ''?'' <> ''model'' AND ''?'' <> ''msdb'' AND ''?'' <> ''tempdb'' AND ''?'' <> ''addresses'' AND ''?'' <> ''ikamebeldizain'' AND ''?'' <> ''new2'' AND ''?'' <> ''sample'' AND ''?'' <> ''sitedatabase'' AND ''?'' <> ''StudentsTeachersTest'' AND ''?'' <> ''MicroinvestDatabasesCatalog'' select * from dbo.system;'
When I try with this query in dataGrid i have just one line (first result).
To append multiple result sets in SQL, you need to have identical results structure (ie: the same columns are returned in the same order) and to tell SQL to bolt them together with a union all (Using just union will remove duplicate rows). To do this across different databases, assuming they are on the same server you can just reference the database in your query:
select *
from Database1.dbo.system
union all
select *
from Database2.dbo.system
If you are trying to do this across a dynamic set of databases, you will only be able to do this with dynamic SQL, which will output the above statement based on a list of databases provided earlier in the script, which you can then execute.
I make a solution:
DECLARE #db_id AS int
DECLARE #db_name AS sysname
CREATE TABLE ##CompatibleDatabases
(
Name sysname,
CompanyName nvarchar(255),
ProductID smallint,
[Version] nvarchar(20),
[Code] int
)
SET ROWCOUNT 0
SELECT dbid AS [ID], Name AS [Name] INTO #AllDatabases FROM master..sysdatabases
SET ROWCOUNT 1
SELECT #db_id = [ID] FROM #AllDatabases
WHILE ##rowcount <> 0
BEGIN
SET ROWCOUNT 0
BEGIN TRY
SET #db_name = db_name(#db_id)
EXEC ('IF (
EXISTS ( SELECT * FROM [' + #db_name + '].INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME=''System'') AND
EXISTS ( SELECT * FROM [' + #db_name + '].INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=''System'' AND COLUMN_NAME=''ProductID'' ) AND
EXISTS ( SELECT * FROM [' + #db_name + '].INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=''System'' AND COLUMN_NAME=''Version'' )
)
BEGIN
DECLARE #insertStatement nvarchar(500)
IF (EXISTS ( SELECT * FROM [' + #db_name + '].INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME=''System'' AND COLUMN_NAME=''CompanyName'' ) )
SET #insertStatement=''INSERT INTO ##CompatibleDatabases SELECT ''''' + #db_name + ''''' AS Name, CompanyName, ProductID, [Version], [Code] FROM [' + #db_name + '].dbo.System''
ELSE
SET #insertStatement=''INSERT INTO ##CompatibleDatabases SELECT ''''' + #db_name + ''''' AS Name,''''' + #db_name + ''''' AS CompanyName, ProductID, [Version], NULL AS Code FROM [' + #db_name + '].dbo.System''
EXEC(#insertStatement)
END')
END TRY
BEGIN CATCH
END CATCH
DELETE #AllDatabases WHERE [ID] = #db_id
SET ROWCOUNT 1
SELECT #db_id = [ID] FROM #AllDatabases
END
SET ROWCOUNT 0
select * from ##CompatibleDatabases
DROP TABLE #AllDatabases
DROP TABLE ##CompatibleDatabases
My sql query returns the below output.
In C#.Net i have to convert it like below based on RowSequence and ColumnSequence column values.
How to do it.
you have to use dynamic pivot as your row value that needs to pivoted is not fixed:
DECLARE #columns AS NVARCHAR(MAX), #query AS NVARCHAR(MAX)
select #columns = STUFF((SELECT ', ' + QUOTENAME(ColumnName)
from YOURTABLE
group by ColumnName, ColumnSequesnce
order by ColumnSequesnce
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = N'SELECT ' + #columns + N' from
(
select RowSequence, ColumnValue, ColumnName
from YOURTABLE
) x
pivot
(
max(ColumnValue)
for ColumnName in (' + #columns + N')
) p '
exec sp_executesql #query;
You can go for Pivot in Sql
http://blog.sqlauthority.com/2008/06/07/sql-server-pivot-and-unpivot-table-examples/
Try it.
I want to PassColumn name as a paremeter in My SP
And if my tat column exists in first table (Batch_Master), want to fatch value from that column,
And if that column exists in my second table (GTIN_Master), want to fetch value from tat table column,
Each table have columns like..
Batch_Master (Batch_M_id, GTIN(primary key),....etc
GTIN_Master (GTIN (foreign key),..etc)
I have Batch_M_id, and column name as a parameter..
Note: column Name having random datatype, some time int or some time datetime etc
I Try followin SP
CREATE PROCEDURE dbo.StoredProcedure2
#columnName varchar(50),
#batchmId int
AS
if exists(select * from sys.columns
where Name = N'columnName' and Object_ID = Object_ID(NBatch_Master'))
begin
select #columnName from Batch_Master
end
else
begin
select #columnName
from GTIN_Master inner join Batch_Master
on GTIN_Master.GTIN = Batch_Master.GTIN
where Batch_M_id =#batchmId
end
RETURN
What you need when you do not know exactly the query structure you are going to execute, then you have to create a dynamic query, which is actually a form of templating queries.
CREATE PROCEDURE dbo.StoredProcedure2
#columnName varchar(50),
#batchmId int
AS
DECLARE #SQL1 AS VARCHAR(MAX)
DECLARE #SQL2 AS VARCHAR(MAX)
SET #SQL1 = 'select ' + #columnName + ' from Batch_Master'
SET #SQL1 = 'select ' + #columnName + '
from GTIN_Master inner join Batch_Master
on GTIN_Master.GTIN = Batch_Master.GTIN
where Batch_M_id =' + CONVERT(VARCHAR,#batchmId)
IF EXISTS(SELECT * FROM sys.columns WHERE Name = #columnName and Object_ID = Object_ID(N'Batch_Master'))
BEGIN
EXEC (#SQL1)
END
ELSE
BEGIN
EXEC (#SQL2)
END
The above will do what you want but is prone to errors. For instance what if the column passed in the parameter does not exist in the tables used in the second query? You should probably need to check for existence in the second case too.
DECLARE #SQL VARCHAR(MAX)
SET #SQL = 'select ' + #columnName + ' from Batch_Master'
EXECUTE(#SQL)
This SQL:
set nocount on
go
create table One (id int, name varchar(25))
go
create table Two (id int, value varchar(25))
go
insert into One values (1, 'Table One')
insert into Two values (1, 'Table Two')
go
create procedure sp_test_colname
#colname sysname
as
declare #sql nvarchar(2048)
if exists (select 1 from sys.columns where name = #colname and object_id = object_id(N'One'))
set #sql = 'select [' + #colname + '] from [One]'
else
if exists (select 1 from sys.columns where name = #colname and object_id = object_id(N'Two'))
set #sql = 'select [' + #colname + '] from [Two]'
if #sql <> ''
exec sp_executesql #sql
go
exec sp_test_colname 'name'
exec sp_test_colname 'value'
exec sp_test_colname 'somethingelse'
go
drop procedure sp_test_colname
drop table One, Two
Returns the following:
name
-------------------------
Table One
value
-------------------------
Table Two
I want to generate a sequence number based on the column value. I want to have this kind of output. I gonna use this in c# .net winform as GridView output
TABLE1
ID Name NoStub
1 arte 3
2 gonzake 2
TABLE2
ID Name StubNumberStart StubNumberEnd
1 arte 0001 0003
2 gonzake 0004 0005
Try this query.. it will give result from Table 2 to Table 1
DECLARE #T1 AS TABLE (ID INT, NAME VARCHAR(50), STUBNUMBER VARCHAR(10))
INSERT INTO #T1 VALUES ( 1, 'ARTE', '001')
INSERT INTO #T1 VALUES ( 1, 'ARTE', '002')
INSERT INTO #T1 VALUES ( 1, 'ARTE', '003')
INSERT INTO #T1 VALUES ( 1, 'GONZAKE', '004')
INSERT INTO #T1 VALUES ( 1, 'GONZAKE', '005')
SELECT * FROM #T1
SELECT DISTINCT ID ,NAME, COUNT(*) AS NOSTUB FROM #T1
GROUP BY ID, NAME
If your request is different from Table 1 to Table 2 then please let me know .. you will get new query...
ALTER PROCEDURE ExpandIt
AS
BEGIN
SET NOCOUNT ON;
DECLARE #Id int;
DECLARE #name varchar(50);
DECLARE #noStub int;
DECLARE #stubNumber char(8);
DECLARE #count as int = 0;
DECLARE #continuedID as int = 0;
DECLARE t1 CURSOR FAST_FORWARD FOR
SELECT ID, Name,NoStub from Table1
OPEN t1
FETCH NEXT FROM t1 INTO #Id, #name, #noStub
WHILE ##FETCH_STATUS = 0
BEGIN
WHILE (#count < #noStub)
BEGIN
SET #count = #count + 1;
SET #stubNumber = ('0000' + CONVERT (CHAR, #continuedID + #count));
SET #stubNumber = SUBSTRING (#stubNumber,LEN(#stubNumber)-4+1, 4);
INSERT INTO Table2 (ID, Name, StubNumber)
VALUES (#Id, #name,#stubNumber);
END
SET #continuedID = #count;
SET #count = 0;
FETCH NEXT FROM t1 INTO #Id, #name, #noStub
END
CLOSE t1 ;
DEALLOCATE t1
END
I need to write a query in t-sql or linq that matches db records that contain the most of the user input words.
exmaple:
nvarchar field in db: "The quick brown fox jumps over the lazy dog"
User input: "brown cow"
The program would match that record because it has the word brown.
let me know if i need to provide more examples.
Assuming you're using T-SQL in a MS SQL Server environment, then you should use Full Text Search technology. It gives you the speed and keeps you away from reinventing the wheel.
We generally use a UDF to split a string into tabular data and can use like command for the same.
declare #searchStr nvarchar(100)
set #searchStr = 'brown fox'
selecT T.* from test T, dbo.fnc_SplitSTring(#searchStr,' ')
where T.name like '%' + token + '%'
CREATE FUNCTION [dbo].[fnc_SplitString]
(
#InString varchar(8000),
#Delim char(1)
)
RETURNS #Return table
(
Position int identity,
Token varchar(100) -- Maximum token size is 100 chars...
)
As
BEGIN
Declare #CR varchar(1),
#LF varchar(1)
Set #CR = char(10)
Set #LF = char(13)
--
If #InString is null return
--
Declare #Pos int
Declare #Pattern char(3)
Set #Pattern = '%' + #Delim + '%'
--
Declare #Token varchar(30)
SELECT #InString = #InString + #Delim -- add trailing delimiter
SELECT #Pos = PATINDEX(#Pattern, #InString)
WHILE (#Pos <> 0) BEGIN
SELECT #Token = ltrim(rtrim(SUBSTRING(#InString, 1, #Pos - 1)))
Select #Token = replace(#Token, #CR, '')
Select #Token = replace(#Token, #LF, '')
Insert #Return Values (#Token)
SELECT #InString = STUFF(#InString, 1, PATINDEX(#Pattern, #InString),'')
SELECT #Pos = PATINDEX(#Pattern, #InString)
END
--
return
--
END