Замените одну строку несколькими строками из другой таблицы - PullRequest
1 голос
/ 29 апреля 2019

У меня есть две таблицы:
Таблица 1:

Number| Code | Value
-------+------+-----
Garden |A0,C2 | 100
Garden |rest  | 500
House  |A0,C2 | 100
House  |rest  | 500

Table2:

|Code|
+-----+
|A0  |
|B1  |
|C2  |
|D3  |
|E4  |

Я бы хотел получить таблицу, которая выглядит примерно так:

Number| Code | Value
-------+------+-----
Garden |A0    | 100
Garden |B1    | 500
Garden |C2    | 100
Garden |D3    | 500
Garden |E4    | 500
House  |A0    | 100
House  |B1    | 500
House  |C2    | 100
House  |D3    | 500
House  |E4    | 500

Кто-нибудь знает инструкцию SQL о том, как мне добраться до этой таблицы

Изменение таблицы 1 или таблицы 2 невозможно

Ответы [ 2 ]

1 голос
/ 29 апреля 2019

Я не фанат этого решения, так как JOIN с EXISTS ужасен. Я настоятельно рекомендую исправить вашу модель данных здесь. Вы не должны использовать данные с разделителями в своей таблице, и вы не должны использовать значение типа 'rest', чтобы обозначить, что вы хотите, чтобы все другие значения отличались от ранее определенных. Полученный здесь результирующий набор является нормализованным набором данных, и именно таким образом вы должны хранить свои данные:

CREATE TABLE Table1 (Number varchar(6), --A number is a varchar?
                     Code varchar(50),
                     [Value] int);

INSERT INTO dbo.Table1 (Number,
                        Code,
                        [Value])
VALUES ('Garden','A0,C2',100),
       ('Garden','rest',500),
       ('House','A0,C2',100),
       ('House','rest',500);

CREATE TABLE Table2 (Code char(2));
INSERT INTO dbo.Table2 (Code)
VALUES ('A0'),
       ('B1'),
       ('C2'),
       ('D3'),
       ('E4');

GO
WITH CTE AS(
    SELECT T1.Number,
           SS.[value] AS Code,
           T1.[Value]
    FROM dbo.Table1 T1
         CROSS APPLY STRING_SPLIT(T1.Code, ',')  SS)
SELECT C.Number,
       T2.Code,
       C.[Value]
FROM CTE C
     JOIN dbo.Table2 T2 ON C.Code = T2.Code
                        OR (C.Code = 'rest'
                       AND  NOT EXISTS (SELECT 1
                                        FROM CTE e
                                        WHERE e.Number = C.Number
                                          AND e.Code = T2.Code))

GO

DROP TABLE dbo.Table1;
DROP TABLE dbo.Table2;                       

дб <> скрипка

Если вы не используете SQL Server 2016+, вы не сможете использовать STRING_SPLIT. В результате я предлагаю поискать «XML Splitter» или delimitedsplit8k(_lead).

1 голос
/ 29 апреля 2019

Вы должны исправить table1, чтобы он не использовал списки, представленные в виде строк с разделителями-запятыми. Вы должны иметь отдельную таблицу для этого. Для этого есть много веских причин.

Предполагая, что вы застряли в чьей-то действительно плохой модели данных, вы можете использовать join. Есть несколько подходов. SQL Server 2017+ имеет встроенную функцию string_split().

Затем вы хотите сгенерировать строки с cross join и ввести значения, которые вы хотите, используя left join s:

select n.number, t2.code, coalesce(t1.value, t1rest.value) as value
from (select distinct number from table1) n cross join
     table2 t2 left join
     table1 t1 
     on t1.number = n.number and ',' + t1.codes + ',' like '%,' + t2.code + ',%' left join
     table1 t1rest
     on t1rest.number = n.number and t1rest.codes = 'rest';

Здесь - это дБ <> скрипка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...