Show unique values only when using CTE - SQL Server - sql

I have the following query:
with GTS_cte AS
(SELECT distinct [BusinessTermID], GTS_T =
STUFF ((SELECT ', ' + dbo.TblField.GTS_table
FROM dbo.TblField
WHERE [BusinessTermID] = Y.[BusinessTermID] AND dbo.TblField.GTS_table <> '' FOR XML PATH('')), 1, 2, '')
FROM dbo.Tblfield AS Y
GROUP BY [BusinessTermID])
,
syn_cte as (
SELECT [BusinessTermID], syns = STUFF
((SELECT ', ' + dbo.TblBusinessSynonym.Synonym
FROM dbo.TblBusinessSynonym
WHERE [BusinessTermID] = x.[BusinessTermID] AND dbo.TblBusinessSynonym.Synonym <> '' FOR XML PATH('')), 1, 2, '')
FROM dbo.TblBusinessSynonym AS x
GROUP BY [BusinessTermID])
select syn_cte.BusinessTermID, syn_cte.syns, GTS_cte.GTS_T
from syn_cte join
GTS_cte on GTS_cte.BusinessTermID = syn_cte.BusinessTermID
It is concatenating the fields correctly and linking them but it is now creating duplicates. My result set looks like this:
Is there a way to show only Unique values in GTS_T?
Thank you

Use DISTINCT inside your Sub-Query.
Try this:
;with GTS_cte AS
(SELECT [BusinessTermID], GTS_T =
STUFF ((SELECT DISTINCT ', ' + dbo.TblField.GTS_table
FROM dbo.TblField
WHERE [BusinessTermID] = Y.[BusinessTermID] AND dbo.TblField.GTS_table <> '' FOR XML PATH('')), 1, 2, '')
FROM dbo.Tblfield AS Y
GROUP BY [BusinessTermID])
,
syn_cte as (
SELECT [BusinessTermID], syns = STUFF
((SELECT DISTINCT ', ' + dbo.TblBusinessSynonym.Synonym
FROM dbo.TblBusinessSynonym
WHERE [BusinessTermID] = x.[BusinessTermID] AND dbo.TblBusinessSynonym.Synonym <> '' FOR XML PATH('')), 1, 2, '')
FROM dbo.TblBusinessSynonym AS x
GROUP BY [BusinessTermID])
select syn_cte.BusinessTermID, syn_cte.syns, GTS_cte.GTS_T
from syn_cte join
GTS_cte on GTS_cte.BusinessTermID = syn_cte.BusinessTermID

Related

Could you help me to solve this simple join issue?i am new to sql so no idea what is wrong with this

SELECT LEVEL_A.VALUE,LEVEL_B.VALUE,LEVEL_C.VALUE,LEVEL_C.VALUE
FROM CUSP_VALUE_LIST_HEADER H
JOIN CUSP_VALUE_LIST_ITEM LEVEL_C
ON H.VALUE_LIST_HEADER_NO = LEVEL_C.VALUE_LIST_HEADER_NO
JOIN (SELECT I.VALUE, I.DESCRIPTION
FROM CUSP_VALUE_LIST_HEADER H
JOIN CUSP_VALUE_LIST_ITEM I
ON H.VALUE_LIST_HEADER_NO = I.VALUE_LIST_HEADER_NO
WHERE H.CAPTION = 'SERVER_ENTITY'
AND LOWER(NVL(I.DESCRIPTION, ' ')) NOT LIKE '%disabled%') LEVEL_A
ON LEVEL_A.VALUE = REGEXP_SUBSTR(LEVEL_C.VALUE, '[^#]+', 1, 1)
JOIN (SELECT I.VALUE, I.DESCRIPTION
FROM CUSP_VALUE_LIST_HEADER H
JOIN CUSP_VALUE_LIST_ITEM I
ON H.VALUE_LIST_HEADER_NO = I.VALUE_LIST_HEADER_NO
WHERE H.CAPTION = 'PurchaseType'
AND LOWER(NVL(I.DESCRIPTION, ' ')) NOT LIKE '%disabled%') LEVEL_B
ON LEVEL_B.VALUE = REGEXP_SUBSTR(LEVEL_C.VALUE, '[^#]+', 1, 1) || '#' ||
REGEXP_SUBSTR(LEVEL_C.VALUE, '[^#]+', 1, 2)
WHERE H.CAPTION = 'PurchaseSubCategoryList'
AND LOWER(NVL(LEVEL_C.DESCRIPTION, ' ')) NOT LIKE '%disabled%'
JOIN (SELECT I.VALUE, I.DESCRIPTION
FROM CUSP_VALUE_LIST_HEADER H
JOIN CUSP_VALUE_LIST_ITEM I
ON H.VALUE_LIST_HEADER_NO = I.VALUE_LIST_HEADER_NO
WHERE H.CAPTION = 'PurchaseCategoryList'
AND LOWER(NVL(I.DESCRIPTION, ' ')) NOT LIKE '%disabled%') LEVEL_D
ON LEVEL_D.VALUE = REGEXP_SUBSTR(LEVEL_C.VALUE, '[^#]+', 1, 1) || '#' ||
REGEXP_SUBSTR(LEVEL_C.VALUE, '[^#]+', 1, 2) || '#' || REGEXP_SUBSTR(LEVEL_C.VALUE, '[^#]+', 1, 3)
WHERE H.CAPTION = 'PurchaseSubCategoryList'
AND LOWER(NVL(LEVEL_C.DESCRIPTION, ' ')) NOT LIKE '%disabled%'
ORDER BY LEVEL_C.VALUE ASC;
First, where is the call of table "LEVEL_A" by some FROM command? This can be corrupting all code. When you input a name with dot and another one, it mean as 'tableName.columnName'. I hope help.

Get value from STUFF function in T-SQL

I have this query:
SELECT STUFF(
(
SELECT ' '+CONVERT(VARCHAR(MAX), R.ID)+' '+O.DisplayName+' : '+CONVERT(NVARCHAR(MAX), R.Value)
FROM AA_V_PHR_CCD_ResultsXResults R
INNER JOIN AA_V_PHR_CCD_ResultsObservationXLANGUAGES O
ON R.IDResultObservation = O.ID
WHERE IDResults = #ID_ESAME AND O.IDLanguage = 2
FOR XML PATH('')
), 1, 1, '') [data];
Now I should to execute this query from my Store Procedure. This query result this Message:
data
1604 HBsAg : 0.140 1605 HBsAb : 0.000 1606 HCV : 0.020
Now I want to put this result in my variables to execute other operation, so I have do this:
BEGIN
DECLARE #TEXT AS NVARCHAR(4000)
SELECT TEXT = STUFF(
(
SELECT ' '+CONVERT(VARCHAR(MAX), R.ID)+' '+O.DisplayName+' : '+CONVERT(NVARCHAR(MAX), R.Value)
FROM AA_V_PHR_CCD_ResultsXResults R
INNER JOIN AA_V_PHR_CCD_ResultsObservationXLANGUAGES O
ON R.IDResultObservation = O.ID
WHERE IDResults = #ID_ESAME AND O.IDLanguage = 2
FOR XML PATH('')
), 1, 1, '') [data];
END
But if I try to execute this code I have an error message:
Incorrect syntax near to 'data'.
Remove the alias:
BEGIN
DECLARE #TEXT AS NVARCHAR(4000)
SELECT TEXT = STUFF(
(
SELECT ' '+CONVERT(VARCHAR(MAX), R.ID)+' '+O.DisplayName+' : '+CONVERT(NVARCHAR(MAX), R.Value)
FROM AA_V_PHR_CCD_ResultsXResults R
INNER JOIN AA_V_PHR_CCD_ResultsObservationXLANGUAGES O
ON R.IDResultObservation = O.ID
WHERE IDResults = #ID_ESAME AND O.IDLanguage = 2
FOR XML PATH('')
), 1, 1, '') [data];
END

Return newest row when several columns are the same

I have a very complex Union query that returns up to two rows. If the second through the 15th columns are identical in both records, I want to return the results of the second record. Otherwise, return the results of the first record which is the newest record. The goal is to return the newest name and address with a pending flag only if the data is not the same.
SELECT TOP 1
1 AS updatePending,
a.entity_number,
a.name_title,
a.name_first,
a.name_middle,
a.name_last,
a.name_suffix,
LTRIM(RTRIM(REPLACE(
LTRIM(RTRIM(ISNULL(a.name_first, ''))) +
CASE WHEN LEN(LTRIM(RTRIM(ISNULL(a.name_first, '')))) = 1 THEN '. ' ELSE ' ' END +
LTRIM(RTRIM(ISNULL(a.name_middle, ''))) +
CASE WHEN LEN(LTRIM(RTRIM(ISNULL(a.name_middle, '')))) = 1 THEN '. ' ELSE ' ' END +
LTRIM(RTRIM(ISNULL(a.name_last, ''))) + ' ' +
LTRIM(RTRIM(ISNULL(a.name_suffix, '')))
,' ',' '))) AS name_full,
NULLIF(LTRIM(RTRIM(
LTRIM(RTRIM(ISNULL(a.company, ''))) +
LTRIM(RTRIM(ISNULL(a.firm_name, ''))))),'') AS company,
a.address1,
a.mailing_address,
a.city,
a.state,
a.zip_code AS zipcode,
a.internet_address AS email_address,
a.time_stamp
FROM statebar.dbo.STAGING_Address_Change_Request a
INNER JOIN Member m ON m.entity_number = a.entity_number
WHERE a.entity_number = (
SELECT m.entity_number
FROM Member m
INNER JOIN Named_Entity ne ON (ne.entity_number = m.entity_number)
WHERE ne.name_last = 'Park'
AND m.birth_year = '1958'
AND m.barno = '12345'
)
AND a.time_stamp > m.time_stamp
UNION ALL
SELECT TOP 1
0 AS updatePending,
ne.entity_number,
ne.name_title,
ne.name_first,
ne.name_middle,
ne.name_last,
ISNULL(ne.name_suffix, ''),
LTRIM(RTRIM(REPLACE(
LTRIM(RTRIM(ISNULL(ne.name_first, ''))) +
CASE WHEN LEN(LTRIM(RTRIM(ISNULL(ne.name_first, '')))) = 1 THEN '. ' ELSE ' ' END +
LTRIM(RTRIM(ISNULL(ne.name_middle, ''))) +
CASE WHEN LEN(LTRIM(RTRIM(ISNULL(ne.name_middle, '')))) = 1 THEN '. ' ELSE ' ' END +
LTRIM(RTRIM(ISNULL(ne.name_last, ''))) + ' ' +
LTRIM(RTRIM(ISNULL(ne.name_suffix, '')))
,' ',' '))) AS name_full,
NULLIF(LTRIM(RTRIM(
LTRIM(RTRIM(ISNULL(ne.company, ''))) +
LTRIM(RTRIM(ISNULL(ne.firm_name, ''))))),'') AS company,
ISNULL(ne.address1, ''),
ne.mailing_address,
ne.city,
ne.state,
ne.zip_code,
ne.internet_address AS email_address,
m.time_stamp
FROM Member m
INNER JOIN Named_Entity ne ON (ne.entity_number = m.entity_number)
LEFT JOIN statebar.dbo.STAGING_Address_Change_Request a ON a.entity_number = m.entity_number
WHERE ne.entity_number = (
SELECT m.entity_number
FROM Member m
INNER JOIN Named_Entity ne ON (ne.entity_number = m.entity_number)
WHERE ne.name_last = 'Park'
AND m.birth_year = '1958'
AND m.barno = '12345'
)
AND m.time_stamp > a.time_stamp
ORDER BY updatePending DESC, a.time_stamp DESC

Concatenating row values using Inner Join

I have this query that I'm using to join two tables for an update statement. This is the query that I built:
DECLARE #DocHoldReasons VARCHAR(8000)
SET #DocHoldReasons = 'DocType Hold'
UPDATE dbo.EpnPackages
SET Error = 1, Msg = COALESCE (#DocHoldReasons + ': ', '') + cv.Value
FROM EpnPackages p
INNER JOIN EpnCountyValues cv ON cv.CountyId = p.CountyId and cv.ValueName = 'DocHoldReason'
WHERE p.Status = 1000
AND p.Error = 0
There are two rows in the EpnCountyValues table with the same ValueName, and I need them both concatenated, and I'm having a tough time doing it. All I can get is the first row value. This is what my resulting string should look like - 'DocType Hold: Test: Test.124.'
eidt: I need the rows with the same ValueName to be concatenated for the update query. There could be more than two rows with ValueName = DocHoldReason
Here's the structure of the EpnCountyValues table:
CountyValueId CountyId ValueName Value
1 1 DocHoldReason Test
2 2 xyz Test1
3 3 DocHoldReason Test.124.
Any help would be greatly appreciated. Thanks!
You can do what you want by pre-aggregating the table before the join. If there are only two values and you don't care about the order, then this will work:
DECLARE #DocHoldReasons VARCHAR(8000);
SET #DocHoldReasons = 'DocType Hold';
UPDATE dbo.EpnPackages
SET Error = 1,
Msg = (COALESCE(#DocHoldReasons + ': ', '') + minv +
(case when minv <> maxv then ': ' + maxv else '' end)
)
FROM EpnPackages p INNER JOIN
(select cv.CountyId, min(cv.value) as minv, max(cv.value) as maxv
from EpnCountyValues cv
where cv.ValueName = 'DocHoldReason'
) cv
ON cv.CountyId = p.CountyId
WHERE p.Status = 1000 AND p.Error = 0;
EDIT:
For more than two values, you have to do string concatenation. That is "unpleasant" in SQL Server. Here is the approach:
DECLARE #DocHoldReasons VARCHAR(8000);
SET #DocHoldReasons = 'DocType Hold';
UPDATE dbo.EpnPackages
SET Error = 1,
Msg = (COALESCE(#DocHoldReasons + ': ', '') +
stuff((select ': ' + cv.value
from EpnCountyValues cv
where cv.ValueName = 'DocHoldReason' and
cv.CountyId = p.CountyId
for xml path ('')
), 1, 2, '')
)
WHERE p.Status = 1000 AND p.Error = 0;
This version does it using a correlated subquery rather than a join with an aggregation.
EDIT II:
You can fix this with an additional coalesce:
DECLARE #DocHoldReasons VARCHAR(8000);
SET #DocHoldReasons = 'DocType Hold';
UPDATE dbo.EpnPackages
SET Error = 1,
Msg = (COALESCE(#DocHoldReasons + ': ', '') +
COALESCE(stuff((select ': ' + cv.value
from EpnCountyValues cv
where cv.ValueName = 'DocHoldReason' and
cv.CountyId = p.CountyId
for xml path ('')
), 1, 2, ''), '')
)
WHERE p.Status = 1000 AND p.Error = 0;
You can join the EpnCountyValues table twice!
Something like this,
DECLARE #DocHoldReasons VARCHAR(8000)
SET #DocHoldReasons = 'DocType Hold'
Select #DocHoldReasons + ': ' + ev1.Value + ': ' + ev2.Value
From EpnPackages p
Join EpnCountyValues ev1 on p.packageID = ev1.packageID
Join EpnCountyValues ev2 on ev1.ValueName = ev2.ValueName
Where ev1.ValueName = 'DocHoldRegion'
And p.status = 1000
And p.error = 0
Does that select look right to you? If so, run the update. I always try to run a select before an update. I have to admit, I'm a bit confused why you're joining on CountyID, but then it seems like you'll be updating the values from different counties?

Generating create table script (with indexes, keys, constrains) for all tables in SQL Server database

If I run the following script
SELECT so.Name, sc.Text
FROM syscomments sc JOIN sysobjects so ON sc.ID = so.ID
I will get all the create procedure/function scripts. Is there something like this for tables, indexes, keys, and triggers?
Thank you for your help!
Nothing inbuilt.
To do it in T-SQL You'd need to find or write your own script. Example here that might get you started.
for SQL 2012 and later use this
I have tried many scripts in web. All of them had flaws. I finally wrote my script using a post in msdn site and changed it to work on many kind of situations.
Note: This scripts works on SQL Server 2012 and later
WITH IndexInfo AS (
SELECT ix.object_id
, ix.NAME AS IndexName
, ix.type_desc
, ix.filter_definition
, ix.is_unique
, ix.is_primary_key
, ix.allow_row_locks
, ix.allow_page_locks
, ds.NAME AS DataSpaceName
, ds.type AS DataSpaceType
, ix.is_padded
, object_schema_name(ix.object_id) AS SchemaName
, object_name(ix.object_id) AS TableName
, IIF(ix.type <= 2, is_included_column, 0) AS HasIncludedColumn
, IIF(ix.type in (5, 6), 1, 0) AS IsColumnStore
, (
SELECT KeyColumns
FROM (
SELECT IC2.object_id
, IC2.index_id
, STUFF((
SELECT ' , ' + C.NAME + IIF(MAX(CONVERT(INT, IC1.is_descending_key)) = 1 AND ix.type <= 2, ' DESC ', ' ')
FROM sys.index_columns IC1
JOIN sys.columns C ON C.object_id = IC1.object_id
AND C.column_id = IC1.column_id
--AND IC1.is_included_column = 0
AND IIF(ix.type <= 2, IC1.is_included_column, 0) = 0
AND IIF(ix.type <= 2, IC1.key_ordinal, ic.index_column_id) > 0
WHERE IC1.object_id = IC2.object_id
AND IC1.index_id = IC2.index_id
GROUP BY IC1.object_id
, C.NAME
, index_id
, IC1.key_ordinal
, IC1.index_column_id
ORDER BY IIF(ix.type <= 2, IC1.key_ordinal, IC1.index_column_id)
FOR XML PATH('')
), 1, 2, '') KeyColumns
FROM sys.index_columns IC2
GROUP BY IC2.object_id
, IC2.index_id
) tmp
WHERE tmp.object_id = ix.object_id
AND tmp.index_id = ix.index_id
) AS KeyColumnsStr
, (
SELECT IncludedColumns
FROM (
SELECT IC2.object_id, IC2.index_id
, STUFF((
SELECT ' , ' + C.NAME
FROM sys.index_columns IC1
JOIN sys.columns C ON C.object_id = IC1.object_id
AND C.column_id = IC1.column_id
--AND IC1.is_included_column = 1
AND IIF(ix.type <= 2, IC1.is_included_column, 0) <> 0
WHERE IC1.object_id = IC2.object_id
AND IC1.index_id = IC2.index_id
--and IIF(ix.type <= 2, IC1.key_ordinal, ic.index_column_id) > 0
GROUP BY IC1.object_id, C.NAME, index_id, IC1.key_ordinal, IC1.index_column_id
ORDER BY IIF(ix.type <= 2, IC1.key_ordinal, IC1.index_column_id)
FOR XML PATH('')
), 1, 2, '') IncludedColumns
FROM sys.index_columns IC2
GROUP BY IC2.object_id, IC2.index_id
) tmp
WHERE tmp.object_id = ix.object_id
AND tmp.index_id = ix.index_id
AND IncludedColumns IS NOT NULL
) AS IncludedColumnsStr
FROM sys.indexes ix
INNER JOIN sys.index_columns ic ON ic.index_id = ix.index_id AND ic.object_id = ix.object_id
INNER JOIN sys.columns col ON col.column_id = ic.column_id AND col.object_id = ix.object_id
INNER JOIN sys.data_spaces ds ON ix.data_space_id = ds.data_space_id
WHERE ix.NAME IS NOT NULL AND IIF(ix.type <= 2, ic.key_ordinal, ic.index_column_id) > 0
)
, Scrpt AS (
SELECT *
, 'CREATE '
+ CASE WHEN is_unique = 1 THEN ' UNIQUE ' ELSE '' END
+ type_desc COLLATE DATABASE_DEFAULT + ' INDEX ' + IndexName + ' ON '
+ SchemaName + '.' + TableName + '(' + KeyColumnsStr + ')'
+ ISNULL(IIF(HasIncludedColumn > 0, ' ', ' INCLUDE (' + IncludedColumnsStr + ')'), '')
+ IIF(filter_definition IS NULL, ' ', ' WHERE ' + filter_definition)
+ ' WITH ('
+ CASE WHEN IsColumnStore = 1 THEN ' DROP_EXISTING = OFF '
ELSE
IIF(is_padded = 1, ' PAD_INDEX = ON ', ' PAD_INDEX = OFF ') + ','
+ ' DROP_EXISTING = OFF ' + ','
+ ' ONLINE = OFF ' + ','
+ IIF(allow_row_locks = 1, ' ALLOW_ROW_LOCKS = ON ', ' ALLOW_ROW_LOCKS = OFF ') + ','
+ IIF(allow_page_locks = 1, ' ALLOW_PAGE_LOCKS = ON ', ' ALLOW_PAGE_LOCKS = OFF ')
END
+ ' ) '
+ IIF(DataSpaceType = 'FG','ON [' + DataSpaceName + ']', '') AS CreateIndexScript
FROM IndexInfo
)
SELECT DISTINCT IndexName, CreateIndexScript
FROM Scrpt
WHERE object_id = object_id('dbo.SWPartition')
As a credit to original author, I mentions the original link here
How to Generate Index Creation Scripts