I have a table with two columns. ParameterName and ParameterValue.
The easy case is when my parameter has a value like this:
The problem is, sometimes, a parameter value can come from another parameter. Like this:
This situation may get more complicated and the second parameter also gets its value from the third parameter and so on...
I know it might be a common case and might have an easy solution but I couldn't find the answer and I don't know what is the name of this type of situation.
Can anyone help me? I need to bring the value for all parameters. I thought the answer was recursive cte but after trying it, it seems it is not the answer.
I put the code for my sample table below:
DECLARE #T TABLE
( ParameterName NVARCHAR(128) NULL,
ParameterValue NVARCHAR(128) NULL
)
INSERT #T
VALUES ( '$A', 'SOME VALUE'),
( '$B', '$A')
SELECT * FROM #T
The answer was recursive CTE and worked like this:
I also added more data to my table.
DECLARE #T TABLE
( ParameterName NVARCHAR(128) NULL,
ParameterValue NVARCHAR(128) NULL
)
INSERT #T
VALUES ( '$A', 'SOME VALUE'),
( '$B', '$A'),
( '$C', 'AAAAA'),
( '$D', '$A'),
( '$E', '$D')
;WITH VALS
AS ( SELECT ParameterName, ParameterValue
FROM #T
WHERE ParameterValue NOT LIKE '$%'
UNION ALL
SELECT T.ParameterName, V.ParameterValue
FROM #T AS T
INNER JOIN VALS AS V ON T.ParameterValue = V.ParameterName
)
SELECT * FROM VALS
Now it works like this:
Related
Create Table #temp
(
Change varchar(20),
deleted_user_id int,
deleted_field_id int,
deleted_value nvarchar (4000),
inserted_user_id int,
inserted_field_id int,
inserted_value nvarchar (4000),
is_difference int,
)
insert into #temp values ('UPDATE','1', '11', '3,2,1,4','1','11','1,2,3,4','0')
insert into #temp values ('UPDATE','1', '12', '','1','12','1,2,3','0')
insert into #temp values ('UPDATE','2', '12', '1,2','2','12','','0')
select * from #temp
I am using Microsoft SQL server management studio
I am trying to compare the deleted value with inserted value. if there is a difference then set is_difference column to 1 or just return the rows.
so far I am thinking to do string split. maybe use stuff function. but not quite sure how to use all these to in a single query or is there any other option. Any help is appreciated. Thanks in advance
this query works so far.
;with cte as
(select isnull(deleted_user_id, inserted_user_id) as user_id,
isnull(deleted_field_id, inserted_field_id) as field_id,
stuff(
(
SELECT ','+ value FROM STRING_SPLIT (deleted_value, ',') group by value order by value FOR XML PATH('')
),1,1,'') as sorted_deleted_value , inserted_value
from #temp )
select * from cte where sorted_deleted_value <> inserted_value
I have this function, but I wanted to pass a table so as to use the same function to get the job done for multiple tables. For example, I want this function work for table1, and table2. But it is just for table1 currently. I was trying to use a dynamic sql in vain; it doesn't pass the parameter selected.
Can someone help? Give me guide on how to pass table as a parameter.
Sample data, table1
CREATE TABLE table1 (id int identity (1,1), name varchar(60))
INSERT INTO table1
VALUES ('a1, a2, a9, a8')
Sample data, table2
CREATE TABLE table2 (id int identity (1,1), name varchar(60))
INSERT INTO table2
VALUES ('a1, a2, a9, a8')
The function:
CREATE FUNCTION f_split
(#id INT)
RETURNS #ab
TABLE (name VARCHAR(20),
ab1 VARCHAR(5)
)
AS
BEGIN
DECLARE #temp TABLE (rn INT, name VARCHAR(5))
INSERT INTO #temp(rn, name)
SELECT ROW_NUMBER() OVER(ORDER BY LTRIM(RTRIM(Split.a.value('.', 'NVARCHAR(MAX)'))) ASC) rn, LTRIM(RTRIM(Split.a.value('.', 'NVARCHAR(MAX)'))) Result
FROM
(
SELECT CAST('<X>'+REPLACE([name], ',', '</X><X>')+'</X>' AS XML) AS String
FROM table1 where id = #id
) AS A
CROSS APPLY String.nodes('/X') AS Split(a)
ORDER BY 1
INSERT INTO #ab
SELECT * FROM #temp
RETURN
END
This gives the result from table1.
SELECT * FROM F_SPLIT(1)
But I want the same function to work for table2 as well.
Any help is appreciated.
Use a partitioned view, which will allow you to specify the table name as a parameter in the where clause.
Start by creating a view that unions the two tables, plus an additional column to indicate which table the row comes from.
CREATE VIEW BothTables AS
SELECT 'Table1' TableName, * FROM Table1
UNION ALL
SELECT 'Table2' TableName, * FROM Table2
Then modify your function. When you pass the table name, use it to select a subset of rows from the view. So instead of
SELECT CAST('<X>'+REPLACE([name], ',', '</X><X>')+'</X>' AS XML) AS String
FROM table1
WHERE id = #id
Use
SELECT CAST('<X>'+REPLACE([name], ',', '</X><X>')+'</X>' AS XML) AS String
FROM BothTables
WHERE TableName = #TableName
AND id = #id
Consider the following query :
DECLARE #T1 TABLE(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Data] VARCHAR(100),
[Column1] VARCHAR(100),
[Column2] VARCHAR(100),
[Column3] VARCHAR(100));
INSERT INTO #T1([Data],[Column1],[Column2],[Column3])
VALUES
('Data1','C11','C21','C31'),
('Data2','C12','C22','C32'),
('Data3','C13','C23','C33'),
('Data4','C14','C24','C34'),
('Data5','C15','C25','C35');
SELECT * FROM #T1;
The output looks like the following:
Now we want to keep the Data column and for each other column stack the result of select for that column into the final table. In other words the following query produces the output:
-- I am looking for a better solution than below!
DECLARE #output TABLE([Data] VARCHAR(100),[Column] VARCHAR(100));
INSERT INTO #output([Data],[Column])
(SELECT [Data],[Column1] FROM #T1
UNION
SELECT [Data],[Column2] FROM #T1
UNION
SELECT [Data],[Column3] FROM #T1)
SELECT * FROM #output
What would be a better cleaner approach than above to produce the final output? As the number of columns increases it means for every single new column I need to have a separate insert which appears to be a crude solution. Ideally I am looking for a pivot-based solution but I couldn't come up with something concrete.
Certainly Yogesh's solution would be more performant. However, since your columns expand over time, here is one approach that will "dynamically" unpivot your data WITHOUT actually using Dynamic SQ:
Example
Select A.[Data]
,C.*
From #T1 A
Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)
Cross Apply (
Select Item = xAttr.value('local-name(.)', 'varchar(100)')
,Value = xAttr.value('.','varchar(100)')
From XMLData.nodes('//#*') xNode(xAttr)
Where xAttr.value('local-name(.)','varchar(100)') not in ('Id','Data','Other-Columns','To-Exclude')
) C
Returns
I often use apply instead of union :
select t1.data, t2.cols
from #t1 t1 cross apply
( values ([column1]), ([column2]), ([column3]) ) t2(cols);
I have data like this I have seen functions and Substring and LEFT ,RIGHT also
but it is not serving my purpose
declare #t table (val varchar(50))
INSERT INTO #t(val)values ('E-001GHDEM120ENDORSEMENT'),
('E-001GHDEM120Renewal'),
('E-001GHDEM120Adjustment'),
('E-001GHDEM120ENDORSEMENT')
select * from #t
output
ENDORSEMENT
Renewal
Adjustment
ENDORSEMENT
I need to use that statement in where condition to filter records
Try this select
DECLARE #t TABLE
(
val VARCHAR(50)
);
INSERT INTO #t
(val
)
VALUES
('E-001GHDEM120ENDORSEMENT'
),
('E-001GHDEM120Renewal'
),
('E-001GHDEM120Adjustment'
),
('E-001GHDEM120ENDORSEMENT'
);
SELECT REVERSE(SUBSTRING(REVERSE(val), 0, PATINDEX('%[^a-zA-Z]%', REVERSE(val)))) AS val
FROM #t;
Try This. From your example here is what i understood.
select right(val,patindex('%[0-9]%', reverse(val))-1)
from #t
I have a table of more than 2 million rows and over 100 columns. I need to run a query that checks if there are any null values in any row or column of the table and return an ID number where there is a null. I've thought about doing the following, but I was wondering if there is a more concise way of checking this?
SELECT [ID]
from [TABLE_NAME]
where
[COLUMN_1] is null
or [COLUMN_2] is null
or [COLUMN_3] is null or etc.
Your method is fine. If your challenge is writing out the where statement, then you can run a query like this:
select column_name+' is null or '
from information_schema.columns c
where c.table_name = 'table_name'
Then copy the results into a query window and use them for building the query.
I used SQL Server syntax for the query, because it looks like you are using SQL Server. Most databases support the INFORMATION_SCHEMA tables, but the syntax for string concatenation varies among databases. Remember to remove the final or at the end of the last comparison.
You can also copy the column list into Excel and use Excel formulas to create the list.
You can use something similar to the following:
declare #T table
(
ID int,
Name varchar(10),
Age int,
City varchar(10),
Zip varchar(10)
)
insert into #T values
(1, 'Alex', 32, 'Miami', NULL),
(2, NULL, 24, NULL, NULL)
;with xmlnamespaces('http://www.w3.org/2001/XMLSchema-instance' as ns)
select ID,
(
select *
from #T as T2
where T1.ID = T2.ID
for xml path('row'), elements xsinil, type
).value('count(/row/*[#ns:nil = "true"])', 'int') as NullCount
from #T as T1