Merge two rows in SQL with only one column being different - sql

Assuming I have a table containing the following information:
FK | Field1 | Field2
---+--------+--------
4 | 103 | 5836
4 | 103 | 5835
FK | Field1 | Field2 | Field2A
---+--------+--------+--------
4 | 103 | 5836 | 5835
Thanks

i think you really need PIVOT, but for an exact dataset in the question, you can follow an approach like below, it's kinda weird and in T-SQl:
declare #a as int
declare #b as int
declare #c as int
declare #query Varchar(Max)
set #query = 'Select 4,103'
DECLARE curs CURSOR FOR
select * From
(select 4 as a , 103 as b , 5836 as c
Union select 4 as a , 103 as b , 5835 as c) as res
OPEN curs
FETCH NEXT FROM curs
INTO #a,#b,#c
WHILE ##FETCH_STATUS = 0
BEGIN
set #query = #query + ','+cast(#c as varchar)
FETCH NEXT FROM curs
INTO #a,#b,#c
END
CLOSE curs;
DEALLOCATE curs;
EXEC(#query)

Related

Get values from 2 Tables in different Databases into another table

I have a Database for say MasterDB which has list of Some Databases Name in a Table tbl_B .Each DataBase Name is identified by an ID.
The structure of the table tbl_B is like the following
tbl_B
ID | DB_Name
-------------
1 | DelhiDB
2 | MumbaiDB
There are DataBases with the same name i.e DelhiDB and MumbaiDB and each of them have a Table with name tbl_C which will have some data for eg.
tbl_C for Delhi
custIDDelhi | custNameDelhi | CustPhoneDelhi |
----------------------------------------------
1 | John | 123456 |
2 | Monika | 789945 |
Please note here that the column names for Both the databases can be Different
Also Please note that DelhiDB and MumbaiDB are separate Database each having a table named tbl_C
I want to create a Table called tblCusotmer_Dictionary in MasterDB
With Data something like this
ColumnName | DataBaseName | DataBaseID | db_ColumnNamme
-----------------------------------------------------------
CustomerID | DelhiDB | 1 | custIDDelhi
CustomerName | DelhiDB | 1 | custNameDelhi
CustomerPhone | DelhiDB | 1 | CustPhoneDElhi
CustomerID | MumbaiDB | 2 | custIDMumbai
CustomerName | MumbaiDB | 2 | custNameMumbai
CustomerPhone | MumbaiDB | 2 | CustPhoneMumbai
Here I dont want any customer data just a list of column name from both the databases along with Database name and ID ,
the column ColumnName in the above table is the Generic Name I am giving to the column db_ColumnNamme
I have taken example for 2 databases and 3 columns for simplicity But there can can be N number for databases each having a table with a same name ( tbl_c here) with fixed no of columns.
Let me know in comments for any clarifications.
if I understood your question correctly then below is the solution which you are looking for. Let me know if it works for you.
DECLARE #tblDatabaseName AS TABLE (Id INT, dbName VARCHAR(100))
--DROP TABLE #tmpREcord
INSERT INTO #tblDatabaseName(id,dbName) VALUES (1,'DelhiDB'),(1,'MumbaiDB')
DECLARE #SQL AS VARCHAR(8000)
DECLARE #Id INT
DECLARE #dbName AS VARCHAR(100)
CREATE TABLE #tmpRecord (
columnName VARCHAR(20),DBID INT, DatabaseName VARCHAR(100))
DECLARE cur_Traverse CURSOR FOR SELECT Id , dbName FROM #tblDatabaseName
OPEN cur_Traverse
FETCH NEXT FROM cur_Traverse INTO #id ,#dbName
WHILE ##FETCH_STATUS =0
BEGIN
SET #SQL = 'INSERT INTO #tmpRecord (ColumnName,DbId,DatabaseName )
SELECT name ,' + CONVERT(VARCHAR(10),#Id) + ' AS DBID, ''' + #dbName + ''' as dbname'
+ ' FROM ' + #dbName + '.sys.all_columns s
WHERE object_Id = (SELECT TOP(1) object_Id FROM ' + #dbName + '.sys.all_objects WHERE name=''tbl_C'')'
PRINT #SQL
EXECUTE (#SQL)
FETCH NEXT FROM cur_Traverse INTO #Id, #dbName
END
CLOSE cur_Traverse
DEALLOCATE cur_Traverse
SELECT * FROM #tmpRecord
You appears to want :
select t.colsname as ColumnName,
b.db_name as DataBaseName,
b.id as DataBaseID,
t.cols as db_ColumnNamme
from tbl_C c
cross apply (values ('custID', 'CustomerID'), ('custName', 'CustomerName'),
('CustPhone', 'CustomerPhone')
) t (cols, colsname)
inner join tbl_B b on b.id = c.custID;

Execute stored procedure with parameter from other table

I have a procedure with one parameter, letsay #AssetID int.
I want to select a column value from another table, then use that value as the parameter for this procedure.
I've stored procedure something like this and the table has been filtered with "Where" criteria from #AssetID parameter:
declare #inspectyear as nvarchar(max), #calc as nvarchar(max), #query as nvarchar(max);
set #inspectyear = STUFF((select distinct ',' + quotename(InspectYear) from ##t2 c
for XML path(''), type).value('.','NVARCHAR(MAX)'),1,1,'')
select #calc = ', ' + quotename(Max(InspectYear)) + ' - ' + quotename(Max(InspectYear)-2)
+ ' as Calc1, ' + quotename(Max(InspectYear)) + ' - ' + quotename(min(InspectYear))
+ ' as Calc2' from #t2;
set #query =
';with data as
(
select inspectyear,
partno, Pos, number
from #t2
unpivot
(
number
for Pos in ([Pos1], [Pos2], [Pos3], [Pos4])
) unpvt
)
select * ' + #calc + ' into ##temp
from data
pivot
(
sum(number)
for inspectyear in (' + #inspectyear + ')
) pvt
order by partno';
exec sp_executesql #query = #query;
select * from ##temp;
drop table ##temp;
So I need to create another procedure, for instance:
create procedure spExecmyProc
as
begin
exec spMyProc '#AssetID' -- <-- The parameter took from other table.
go
end
The #date parameter, took from other table.
Is it possible to do that? The result should be only one result.
So far, this is what I did. It works, but the result is not on "one result". It create more than one result if the #AssetID is more than one:
declare #AssetID int;
declare cur CURSOR FOR
select distinct AssetID from myTable
open cur
fetch next from cur into #AssetID
while ##FETCH_STATUS = 0
begin
exec mySPName #AssetID
fetch next from cur into #AssetID
end
close cur
DEALLOCATE cur
Thank you.
I'm not 100% sure I understand what you're trying to achieve, but if you want to be able to be able to run some code on each value of AssetID in mytable, returning just one result for each input value, I think you could use a Scalar-valued Function. Let's pretend that the purpose of your original stored procedure was just to increment the AssetId value by 1 for simplicity - your function could be created like this:
CREATE FUNCTION fnMyFunction (#AssetId INT)
RETURNS INT
AS
BEGIN
DECLARE #return INT
SET #return = #AssetId + 1
RETURN #return
END
If you then have some values in a table:
CREATE TABLE Assets (
AssetId INT
)
INSERT INTO Assets
SELECT 1
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 5
UNION
SELECT 7
UNION
SELECT 5
You can call your function on each value you return:
SELECT AssetId,
dbo.fnMyFunction(AssetId) AS AssetIdPlus1
FROM Assets
Which gives these results for my super simple dataset defined above:
/------------------------\
| AssetId | AssetIdPlus1 |
|---------+--------------|
| 1 | 2 |
| 2 | 3 |
| 3 | 4 |
| 5 | 6 |
| 7 | 8 |
| 5 | 6 |
\------------------------/
If you just want to get the result for each unique value of AssetId in your table, then just return the DISTINCT results:
SELECT DISTINCT
AssetId,
dbo.fnMyFunction(AssetId)
FROM Assets
which would give these results for the same dataset above (with just one row for AssetId = 5):
/------------------------\
| AssetId | AssetIdPlus1 |
|---------+--------------|
| 1 | 2 |
| 2 | 3 |
| 3 | 4 |
| 5 | 6 |
| 7 | 8 |
\------------------------/

SQL Evaluate formula stored in database

Is it possible to evaluate a string formula/expression stored in a column? (SQL Server 2014).
Example:
TABLE:
ID | Formula
1 | IIF(2<3,'A','B')
2 | IIF(3<4,'C','D')
3 | IIF(5<1,'E','F')
Query:
SELECT ID, Eval(Formula)
Output:
1 | A
2 | C
3 | F
With Dynamic SQL, but REALLY not recommended. Just in case you REALLY have to...
Declare #YourTable table (ID int,Formula varchar(100))
Insert Into #YourTable values
(1,'IIF(2<3,''A'',''B'')'),
(2,'IIF(3<4,''C'',''D'')'),
(3,'IIF(5<1,''E'',''F'')')
Declare #SQL varchar(max) = '>>>'
Select #SQL = Replace(#SQL + concat(' Union All Select ID=',ID,',Value=',Formula),'>>> Union All','')
From #YourTable
Exec (#SQL)
Returns
ID Value
1 A
2 C
3 F

How to do foreach select in single SQL query

I have a problem, i try to do a foreach to select multi row and do a select in a each one.
This is my table :
| TRANSLATION_ID | TABLE_NAME | COLUMN_NAME | ID_COLUMN | CODELANGUE_COLUMN |
|---------------- |------------------------- |------------- |----------- |------------------- |
| 1 | CHAMPS_LANGUE | VALUE1 | ZZZ | CODELANGUE |
| 2 | DELAIS_LIBELLES | VALUE2 | YYY | CODELANGUE |
| 3 | MODELES_ENQUETES_LIGNES | VALUE3 | XXX | CODELANGUE |
| ... | ... | ... | ... | |
And I would like to do multiple SELECT on every TABLE like CHAMPS_LANGUE , DELAIS_LIBELLES etc..
FOREACH TABLE_NAME
SELECT COLUM_NAME, ID_COLUM FROM TABLE_NAME WHERE CODELANGUE = 1
Let me know if a not very explicit. :)
Modified an answer by #legendofawesomeness found here to make it more relevant for your situation
--Cursor for iterating
DECLARE #tableCursor CURSOR
DECLARE #TABLE_NAME NVARCHAR(255)
DECLARE #COLUM_NAME NVARCHAR(255)
DECLARE #ID_COLUM NVARCHAR(255)
DECLARE #CODELANGUE_COLUMN NVARCHAR(255)
SET #tableCursor = CURSOR FOR SELECT TABLE_NAME, COLUM_NAME, ID_COLUMN, CODELANGUE_COLUMN FROM [tableData] -- Substitute with the name of your table as given in your question (which you didn't specify)
OPEN #tableCursor
FETCH NEXT FROM #tableCursor INTO #TABLE_NAME, #COLUM_NAME, #ID_COLUMN, #CODELANGUE_COLUMN
WHILE (##fetch_status = 0)
BEGIN
--dynamic sql
DECLARE #sql NVARCHAR(max)
--Your logic here...
SET #sql = 'SELECT ' + #COLUM_NAME + ', ' + #ID_COLUM + ' FROM ' + #TABLE_NAME + ' WHERE ' + #CODELANGUE_COLUMN + ' = 1'
EXEC dbo.sp_executesql #sql
FETCH NEXT FROM #tableCursor INTO #TABLE_NAME, #COLUM_NAME, #ID_COLUMN, #CODELANGUE_COLUMN
END
CLOSE #tableCursor
DEALLOCATE #tableCursor

Query to split String value into multiple rows

i have
id | dvr
1 | 1,2,3
2 | 1,3,4
3 | 1,5,6,7,8
and would like to have
id | dvr
1 | 1
1 | 2
1 | 3
2 | 1
2 | 3
2 | 4
... and so on
what is the fastest query i should use?
Make a sql function as below:
create Function [dbo].[fun_CSVToTable]
(
#LIST varchar(7000),
#Delimeter varchar(10)
)
RETURNS #RET1 TABLE (RESULT BIGINT)
AS
BEGIN
DECLARE #RET TABLE(RESULT BIGINT)
IF LTRIM(RTRIM(#LIST))='' RETURN
DECLARE #START BIGINT
DECLARE #LASTSTART BIGINT
SET #LASTSTART=0
SET #START=CHARINDEX(#Delimeter,#LIST,0)
IF #START=0
INSERT INTO #RET VALUES(SUBSTRING(#LIST,0,LEN(#LIST)+1))
WHILE(#START >0)
BEGIN
INSERT INTO #RET VALUES(SUBSTRING(#LIST,#LASTSTART,#START-#LASTSTART))
SET #LASTSTART=#START+1
SET #START=CHARINDEX(#Delimeter,#LIST,#START+1)
IF(#START=0)
INSERT INTO #RET VALUES(SUBSTRING(#LIST,#LASTSTART,LEN(#LIST)+1))
END
INSERT INTO #RET1 SELECT * FROM #RET
RETURN
END
If you are running postgresql and dvr column is text you could do:
select
id,
unnest(string_to_array(dvr,','))
from your_table;