简体   繁体   中英

Unique roecords with CTE and UNION

I have one table consists of three fields, TagID, AlarmInfo and Description. TagID always starts with a prefix followed by "_HH", "_H","_L","_LL" OR the suffix can be customizing. If the suffix is customizing, then AlarmInfo must be specified. The AlarmInfo field consists of two parts, alarm type and order index.

Ex table 在此处输入图片说明

I've tried something like that:

Code:

WITH
CTE1 AS
(
SELECT [TagID],[AlarmInfo],[Description],CASE WHEN [AlarmInfo] = ''  OR [AlarmInfo] IS NULL OR CHARINDEX('|',[AlarmInfo],0) = 0 THEN 999 
ELSE IIF(ISNUMERIC(REVERSE(SUBSTRING(REVERSE([AlarmInfo]),1,CHARINDEX('|',REVERSE([AlarmInfo]),0)-1))) = 1,
CAST(REVERSE(SUBSTRING(REVERSE([AlarmInfo]),1,CHARINDEX('|',REVERSE([AlarmInfo]),0)-1)) AS INT),999) END AS [OrderIndex],
CASE WHEN [TagID] LIKE '%_%' THEN LEFT([TagID],CHARINDEX('_',[TagID])-1) ELSE [TagID] END TagPrefix 
FROM Table1),

CTE2 AS (SELECT [TagID],[AlarmInfo],[Description], 1 [OrderIndex] FROM Table1 WHERE TagID  LIKE '%FT01_HH'),
CTE3 AS (SELECT [TagID],[AlarmInfo],[Description], 4 [OrderIndex] FROM Table1 WHERE TagID  LIKE '%FT01_LL')

SELECT [TagID],[AlarmInfo],[Description],[OrderIndex] FROM CTE1 WHERE (TagPrefix = 'FT01') AND [AlarmInfo] LIKE 'AlarmLimit%'-- 
UNION
SELECT * FROM CTE2
UNION
SELECT * FROM CTE3
ORDER BY [OrderIndex] ASC

在此处输入图片说明

The result is that the FT01_LL is duplicated. If I remove [OrderIndex] from the Query, then UNION return only unique rows, but then I am missing the imported order index information.

在此处输入图片说明

I am using MS SQL server 2014.

I am only posting this as an answer because it is too long for a comment. (I am new here so if I am breaking a rule please let me know)

Using this test set with your code I am not getting duplicates.

DECLARE @AlarmInfo TABLE
      (
          TagId        VARCHAR(50)
         ,AlarmInfo    VARCHAR(50)
         ,AlarmDesc    VARCHAR(50)
         ,AlarmComment VARCHAR(50)
      );

INSERT INTO @AlarmInfo
     (
         TagId
        ,AlarmInfo
        ,AlarmDesc
        ,AlarmComment
     )
VALUES
     ('FT01_HH'         -- TagId - varchar(50)
     ,''                -- AlarmInfo - varchar(50)
     ,'High-high alarm' -- AlarmDesc - varchar(50)
     ,'Predefined'      -- AlarmComment - varchar(50)
    )
    ,('FT01_Custom1', 'AlarmLimit|2', 'Custom Alarm 1', 'Custom')
    ,('FT01_Custom2', 'AlarmLimit|3', 'Custom Alarm 2', 'Custom')
    ,('FT01_LL', 'AlarmLimit|4', 'Low-Level alarm', 'Predefined ...');

WITH CTE1
    AS (
           SELECT TagID
                 ,AlarmInfo
                 ,AlarmDesc
                 ,OrderIndex = CASE
                                   WHEN AlarmInfo = ''
                                        OR AlarmInfo IS NULL
                                        OR CHARINDEX('|', AlarmInfo, 0) = 0
                                       THEN 999
                                   ELSE
                                       IIF(
                                           ISNUMERIC(REVERSE(SUBSTRING(
                                                                          REVERSE(AlarmInfo)
                                                                         ,1
                                                                         ,CHARINDEX('|', REVERSE(AlarmInfo), 0) - 1
                                                                      )
                                                            )
                                                    ) = 1
                                          ,CAST(REVERSE(SUBSTRING(
                                                                     REVERSE(AlarmInfo)
                                                                    ,1
                                                                    ,CHARINDEX('|', REVERSE(AlarmInfo), 0) - 1
                                                                 )
                                                       ) AS INT)
                                          ,999)
                               END
                 ,TagPrefix = CASE
                                  WHEN TagID LIKE '%_%'
                                      THEN LEFT(TagID, CHARINDEX('_', TagID) - 1)
                                  ELSE
                                      TagID
                              END
             FROM @AlarmInfo AS ai
       )
    ,CTE2
    AS (
           SELECT TagID
                 ,AlarmInfo
                 ,ai.AlarmDesc
                 ,OrderIndex = 1
             FROM @AlarmInfo AS ai
            WHERE TagID LIKE '%FT01_HH'
       )
    ,CTE3
    AS (
           SELECT TagID
                 ,AlarmInfo
                 ,AlarmDesc
                 ,OrderIndex = 4
             FROM @AlarmInfo AS ai
            WHERE TagID LIKE '%FT01_LL'
       )
SELECT TagID
      ,AlarmInfo
      ,CTE1.AlarmDesc
      ,OrderIndex
  FROM CTE1
 WHERE (TagPrefix = 'FT01')
       AND AlarmInfo LIKE 'AlarmLimit%' -- 
UNION
SELECT *
  FROM CTE2
UNION
SELECT *
  FROM CTE3
 ORDER BY OrderIndex ASC;

Here is the result set:

TagID                                              AlarmInfo                                          AlarmDesc                                          OrderIndex
-------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -----------
FT01_HH                                                                                               High-high alarm                                    1
FT01_Custom1                                       AlarmLimit|2                                       Custom Alarm 1                                     2
FT01_Custom2                                       AlarmLimit|3                                       Custom Alarm 2                                     3
FT01_LL                                            AlarmLimit|4                                       Low-Level alarm                                    4

Can you tell me what you need help with?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM