мульти значение в одной записи sql - PullRequest
0 голосов
/ 23 декабря 2018

У меня есть 4 таблицы:

  1. Основная таблица Applications с такими образцами данных:

    Id | Craft_Name | Area     | PPE       | Potential
    ---+------------+----------+-----------+-------------
     1 | anas       | 1, 2, 3, | 4, 1, 3,  | 4, 2, 
    
  2. Вторая таблица Area:

    Id | Area
    ---+----------
     1 | Jordan
     2 | USA
     3 | China
    
  3. третий стол PPE

    Id | PPE 
    ---+-----------------
     1 | Safety Shoes   
     2 | Safety Gloves  
     3 | Electrical Gloves
     4 | Thermal Gloves 
    
  4. Четвертый стол Potential:

    ID | Potential
    ---+----------------------
     1 | Working at Height
     2 | Falling Objects
     3 | Sharp Edges
     4 | Inhalation
    

Наконец, мне нужен результат SQL-запроса:

Id | Craft_Name | Area                | PPE                                                   | Potential
---+------------+---------------------+-------------------------------------------------------+-----------------------------
 1 | anas       | Jordan, USA, China, | Thermal Gloves, Working at Height, Electrical Gloves, | Inhalation, Falling Objects, 

Ответы [ 2 ]

0 голосов
/ 23 декабря 2018

вы можете сделать это двумя способами.

  1. , чтобы изменить структуру таблиц ваших приложений, добавив в нее новые таблицы отношений 3 ко многим.(рекомендуется и проще выполнять любые типы при анализе)
  2. или вы можете использовать следующий сложный код, объединяющий в себе множество сложных запросов.

    IF OBJECT_ID('tempdb..#AreaTable') IS NOT NULL
        DROP TABLE #AreaTable
    IF OBJECT_ID('tempdb..#PPETable') IS NOT NULL
        DROP TABLE #PPETable
    
    ; WITH AreaTable AS (
        SELECT 
            A.ID, A.CreaftName, AreaName
        FROM  
            (
                SELECT T1.ID, T1.CreaftName,T1.[AreaIDs],T2.my_Splits
                FROM
                    (
                        SELECT *,
                            CAST('<X>'+replace([AreaIDs],',','</X><X>')+'</X>' as XML) as my_Xml 
                        FROM [dbo].[Applications]) T1
                        CROSS APPLY
                        (
                            SELECT 
                                my_Data.D.value('.','varchar(50)') as my_Splits
                            FROM 
                                T1.my_Xml.nodes('X') as my_Data(D)
                        ) T2
                    ) A 
        INNER JOIN [dbo].[Areas] B on A.my_splits = B.ID
    )
    
    --SELECT * FROM TempTable
    
    SELECT DISTINCT ST2.ID, St2.CreaftName,
        SUBSTRING(
            (
                SELECT ','+ ST1.AreaName  AS [text()]
                FROM AreaTable ST1
                WHERE ST1.ID = ST2.ID
                ORDER BY ST1.ID
                FOR XML PATH ('')
            ), 2, 1000) [Areas]
    INTO #AreaTable
    FROM [dbo].[Applications] ST2
    
    ;WITH PPETable AS (
        SELECT 
            A.ID, A.CreaftName, PPEName
        FROM  
            (
                SELECT T1.ID, T1.CreaftName,T1.PPEIDs,T2.my_Splits
                FROM
                    (
                        SELECT *,
                            CAST('<X>'+replace(PPEIDs,',','</X><X>')+'</X>' as XML) as my_Xml 
                        FROM [dbo].[Applications]) T1
                        CROSS APPLY
                        (
                            SELECT 
                                my_Data.D.value('.','varchar(50)') as my_Splits
                            FROM 
                                T1.my_Xml.nodes('X') as my_Data(D)
                        ) T2
                    ) A 
        INNER JOIN [dbo].[PPE] B on A.my_splits = B.ID
    )
    
    --SELECT * FROM TempTable
    
    SELECT DISTINCT ST2.ID, St2.CreaftName,
        SUBSTRING(
            (
                SELECT ','+ ST1.PPEName  AS [text()]
                FROM PPETable ST1
                WHERE ST1.ID = ST2.ID
                ORDER BY ST1.ID
                FOR XML PATH ('')
            ), 2, 1000) [PPEs]
    INTO #PPETable
    FROM [dbo].[Applications] ST2
    
    SELECT MainTable.ID, MainTable.CreaftName, A.Areas, B.[PPEs]
    FROM 
        [dbo].[Applications] AS MainTable
        LEFT OUTER JOIN #AreaTable AS A ON MainTable.ID = A.ID
        LEFT OUTER JOIN #PPETable AS B ON MainTable.ID = B.ID
    
    
    IF OBJECT_ID('tempdb..#AreaTable') IS NOT NULL
        DROP TABLE #AreaTable
    IF OBJECT_ID('tempdb..#PPETable') IS NOT NULL
        DROP TABLE #PPETable
    

, и вы можете использовать следующий код для генерации таблиц, с которыми я создал этот скрипт, для вашей справки

    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[PPE]') AND type in (N'U'))
    DROP TABLE [dbo].[PPE]
    GO
    /****** Object:  Table [dbo].[Areas]    Script Date: 23/12/2018 10:43:40 AM ******/
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Areas]') AND type in (N'U'))
    DROP TABLE [dbo].[Areas]
    GO
    /****** Object:  Table [dbo].[Applications]    Script Date: 23/12/2018 10:43:40 AM ******/
    IF  EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Applications]') AND type in (N'U'))
    DROP TABLE [dbo].[Applications]
    GO
    /****** Object:  Table [dbo].[Applications]    Script Date: 23/12/2018 10:43:40 AM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Applications]') AND type in (N'U'))
    BEGIN
    CREATE TABLE [dbo].[Applications](
        [ID] [int] IDENTITY(1,1) NOT NULL,
        [CreaftName] [nvarchar](50) NULL,
        [AreaIDs] [nvarchar](50) NULL,
        [PPEIDs] [nvarchar](50) NULL,
        CONSTRAINT [PK_Applications] PRIMARY KEY CLUSTERED 
    (
        [ID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    END
    GO
    /****** Object:  Table [dbo].[Areas]    Script Date: 23/12/2018 10:43:40 AM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Areas]') AND type in (N'U'))
    BEGIN
    CREATE TABLE [dbo].[Areas](
        [ID] [int] IDENTITY(1,1) NOT NULL,
        [AreaName] [nvarchar](50) NULL,
        CONSTRAINT [PK_Ares] PRIMARY KEY CLUSTERED 
    (
        [ID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    END
    GO
    /****** Object:  Table [dbo].[PPE]    Script Date: 23/12/2018 10:43:40 AM ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[PPE]') AND type in (N'U'))
    BEGIN
    CREATE TABLE [dbo].[PPE](
        [ID] [int] IDENTITY(1,1) NOT NULL,
        [PPEName] [nvarchar](50) NULL,
        CONSTRAINT [PK_PPE] PRIMARY KEY CLUSTERED 
    (
        [ID] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    END
    GO
    SET IDENTITY_INSERT [dbo].[Applications] ON 

    INSERT [dbo].[Applications] ([ID], [CreaftName], [AreaIDs], [PPEIDs]) VALUES (1, N'Anas', N'1,3,2,', N'1,3')
    INSERT [dbo].[Applications] ([ID], [CreaftName], [AreaIDs], [PPEIDs]) VALUES (2, N'Islam', N',6,5,3', N'2')
    INSERT [dbo].[Applications] ([ID], [CreaftName], [AreaIDs], [PPEIDs]) VALUES (3, N'Mohammad', N'4', NULL)
    SET IDENTITY_INSERT [dbo].[Applications] OFF
    SET IDENTITY_INSERT [dbo].[Areas] ON 

    INSERT [dbo].[Areas] ([ID], [AreaName]) VALUES (1, N'Jordan')
    INSERT [dbo].[Areas] ([ID], [AreaName]) VALUES (2, N'China')
    INSERT [dbo].[Areas] ([ID], [AreaName]) VALUES (3, N'USA')
    INSERT [dbo].[Areas] ([ID], [AreaName]) VALUES (4, N'Colombia')
    INSERT [dbo].[Areas] ([ID], [AreaName]) VALUES (5, N'Costa Rica')
    INSERT [dbo].[Areas] ([ID], [AreaName]) VALUES (6, N'Panama')
    SET IDENTITY_INSERT [dbo].[Areas] OFF
    SET IDENTITY_INSERT [dbo].[PPE] ON 

    INSERT [dbo].[PPE] ([ID], [PPEName]) VALUES (1, N'Safety Shoes')
    INSERT [dbo].[PPE] ([ID], [PPEName]) VALUES (2, N'Safety Gloves')
    INSERT [dbo].[PPE] ([ID], [PPEName]) VALUES (3, N'Electrical Gloves')
    SET IDENTITY_INSERT [dbo].[PPE] OFF
0 голосов
/ 23 декабря 2018

Например - Таблица областей (продолжить другие таблицы)

select 
    (select Area.Area + ',' 
     from dbo.Area 
     where charindex(',' + cast(Area.Id as varchar(10)) + ',', ',' + isnull(Applications.Area, '') + ',') > 0 
     for xml path('')) 
from 
    dbo.Applications
...