Как получить соседние столбцы объединяемых таблиц в строках вместо столбцов? - PullRequest
1 голос
/ 26 июня 2019

У меня есть три таблицы A_PRODUCT, A_MODEL и A_AREA. Эти таблицы могут быть объединены с использованием PRODUCT_ID. Они имеют разное количество столбцов, то есть A_PRODUCT имеет 6 столбцов, A_MODEL имеет 4 столбца и A_AREA имеет 3 столбца.

Я хочу получить вывод, такой, чтобы за строкой из таблицы A_PRODUCT следовали строки из таблицы A_MODEL, а затем строки из таблицы A_AREA для продукта.

Обратите внимание, что продукт может иметь несколько версий. Например: продукт «P-1» имеет две версии «V-1» и «V-2».

Ниже приведены операторы SQL для создания образцов данных:

CREATE TABLE A_PRODUCT
(
PRODUCT_ID NVARCHAR(30),
PRODUCT_VID NVARCHAR(30),
PRODUCT_NAME NVARCHAR(30),
PRODUCT_NICK_NAME NVARCHAR(30),
PRODUCT_DESC NVARCHAR(30),
PRODUCT_CATEGORY NVARCHAR(30)
);

INSERT INTO A_PRODUCT (PRODUCT_ID, PRODUCT_VID, PRODUCT_NAME, PRODUCT_NICK_NAME, PRODUCT_DESC, PRODUCT_CATEGORY)
VALUES ('P-1', 'V-1', 'LONG-SLEEVE LOGO JERSEY', 'JERSEY', 'SLEEVE JERSEY', 'SHIRT');

INSERT INTO A_PRODUCT (PRODUCT_ID, PRODUCT_VID, PRODUCT_NAME, PRODUCT_NICK_NAME, PRODUCT_DESC, PRODUCT_CATEGORY)
VALUES ('P-1', 'V-2', 'LONG-SLEEVE LOGO JERSEY', 'JERSEY', 'SLEEVE JERSEY', 'SHIRT');

INSERT INTO A_PRODUCT (PRODUCT_ID, PRODUCT_VID, PRODUCT_NAME, PRODUCT_NICK_NAME, PRODUCT_DESC, PRODUCT_CATEGORY)
VALUES ('P-2', 'V-1', 'RAY-BAN SUN GLASSES', 'RAY-BAN', 'RAY-BAN SUN GLASSES', 'GLASSES');

-- DROP TABLE A_MODEL;
CREATE TABLE A_MODEL
(
MODEL_ID NVARCHAR(30),
MODEL_NAME NVARCHAR(30),
PRODUCT_ID NVARCHAR(30),
MODEL_YEAR NVARCHAR(30)
);

INSERT INTO A_MODEL (MODEL_ID, MODEL_NAME, PRODUCT_ID, MODEL_YEAR)
VALUES ('M-1', 'REEBOK', 'P-1', '2003');

INSERT INTO A_MODEL (MODEL_ID, MODEL_NAME, PRODUCT_ID, MODEL_YEAR)
VALUES ('M-2', 'RAY-BAN', 'P-2', '2004');

INSERT INTO A_MODEL (MODEL_ID, MODEL_NAME, PRODUCT_ID, MODEL_YEAR)
VALUES ('M-3', 'ARMANI', 'P-2', '2007');

CREATE TABLE A_AREA
(
AREA_ID NVARCHAR(30),
AREA_NAME NVARCHAR(30),
PRODUCT_ID NVARCHAR(30)
);

INSERT INTO A_AREA (AREA_ID, AREA_NAME, PRODUCT_ID)
VALUES ('A-1', 'SOUTH', 'P-1');

INSERT INTO A_AREA (AREA_ID, AREA_NAME, PRODUCT_ID)
VALUES ('A-2', 'NORTH', 'P-1');

INSERT INTO A_AREA (AREA_ID, AREA_NAME, PRODUCT_ID)
VALUES ('A-3', 'EAST', 'P-1');

INSERT INTO A_AREA (AREA_ID, AREA_NAME, PRODUCT_ID)
VALUES ('A-4', 'WEST', 'P-1');

INSERT INTO A_AREA (AREA_ID, AREA_NAME, PRODUCT_ID)
VALUES ('A-5', 'SOUTH-WEST', 'P-2');

Ожидаемый результат такой:

|PRODUCT|P-1|V-1|LONG-SLEEVE LOGO JERSEY|JERSEY|SLEEVE JERSEY|SHIRT|
|MODEL|M-1|REEBOK|2003|
|AREA|A-1|SOUTH|
|AREA|A-2|NORTH|
|AREA|A-3|EAST|
|AREA|A-4|WEST|
|PRODUCT|P-1|V-2|LONG-SLEEVE LOGO JERSEY|JERSEY|SLEEVE JERSEY|SHIRT|
|MODEL|M-1|REEBOK|2003|
|AREA|A-1|SOUTH|
|AREA|A-2|NORTH|
|AREA|A-3|EAST|
|AREA|A-4|WEST|
|PRODUCT|P-2|V-1|RAY-BAN SUN GLASSES|RAY-BAN|RAY-BAN SUN GLASSES|GLASSES|
|MODEL|M-2|RAY-BAN|2004|
|MODEL|M-3|ARMANI|2007|
|AREA|A-5|SOUTH-WEST|

Как вы можете видеть, вывод представляет собой полный снимок версии продукта. Снимки товара могут появляться в любом порядке. Например, следующий вывод действителен:

|PRODUCT|P-1|V-2|LONG-SLEEVE LOGO JERSEY|JERSEY|SLEEVE JERSEY|SHIRT|
|MODEL|M-1|REEBOK|2003|
|AREA|A-1|SOUTH|
|AREA|A-2|NORTH|
|AREA|A-3|EAST|
|AREA|A-4|WEST|
|PRODUCT|P-1|V-1|LONG-SLEEVE LOGO JERSEY|JERSEY|SLEEVE JERSEY|SHIRT|
|MODEL|M-1|REEBOK|2003|
|AREA|A-1|SOUTH|
|AREA|A-2|NORTH|
|AREA|A-3|EAST|
|AREA|A-4|WEST|
|PRODUCT|P-2|V-1|RAY-BAN SUN GLASSES|RAY-BAN|RAY-BAN SUN GLASSES|GLASSES|
|MODEL|M-2|RAY-BAN|2004|
|MODEL|M-3|ARMANI|2007|
|AREA|A-5|SOUTH-WEST|

1 Ответ

2 голосов
/ 26 июня 2019

Это не полностью оптимизировано для производительности, но должно быть легко понять:

WITH CTE
AS (
    SELECT
        ap.PRODUCT_ID
       ,ap.PRODUCT_VID
       ,ap.PRODUCT_NAME
       ,ap.PRODUCT_NICK_NAME
       ,ap.PRODUCT_DESC
       ,ap.PRODUCT_CATEGORY
       ,am.MODEL_NAME
       ,am.MODEL_ID
       ,am.MODEL_YEAR
       ,aa.AREA_ID
       ,aa.AREA_NAME
    FROM dbo.A_PRODUCT ap
    INNER JOIN A_MODEL am
        ON ap.PRODUCT_ID = am.PRODUCT_ID
    INNER JOIN A_AREA aa
        ON ap.PRODUCT_ID = aa.PRODUCT_ID
),
CTE_P
AS (
    SELECT DISTINCT
        c.PRODUCT_ID
       ,c.PRODUCT_VID
       ,'1'                 AS [ORDER_ID]
       ,'PRODUCT'           AS [COL1]
       ,c.PRODUCT_ID        AS [COL2]
       ,c.PRODUCT_VID       AS [COL3]
       ,c.PRODUCT_NAME      AS [COL4]
       ,c.PRODUCT_NICK_NAME AS [COL5]
       ,c.PRODUCT_DESC      AS [COL6]
       ,c.PRODUCT_CATEGORY  AS [COL7]
    FROM CTE c
),
CTE_MODEL
AS (
    SELECT DISTINCT
        c.PRODUCT_ID
       ,c.PRODUCT_VID
       ,'2'             AS [ORDER_ID]
       ,'MODEL'         AS [COL1]
       ,c.MODEL_ID      AS [COL2]
       ,c.MODEL_NAME    AS [COL3]
       ,c.MODEL_YEAR    AS [COL4]
       ,NULL            AS [COL5]
       ,NULL            AS [COL6]
       ,NULL            AS [COL7]
    FROM CTE c
),
CTE_AREA
AS (
    SELECT DISTINCT
        PRODUCT_ID
       ,PRODUCT_VID
       ,'3'       AS [ORDER_ID]
       ,'AREA'    AS [COL1]
       ,AREA_ID   AS [COL2]
       ,AREA_NAME AS [COL3]
       ,NULL      AS [COL4]
       ,NULL      AS [COL5]
       ,NULL      AS [COL6]
       ,NULL      AS [COL7]
    FROM CTE
)

SELECT
       -- t.COL1
       --,t.COL2
       --,t.COL3
       --,t.COL4
       --,t.COL5
       --,t.COL6
       --,t.COL7,
        ISNULL('|' + t.COL1 + '|', '')  + 
        ISNULL(t.COL2 + '|', '')  + 
        ISNULL(t.COL3 + '|', '')  + 
        ISNULL(t.COL4 + '|', '')  + 
        ISNULL(t.COL5 + '|', '')  + 
        ISNULL(t.COL6 + '|', '')  + 
        ISNULL(t.COL7 + '|', '')  AS Result
    FROM (
        SELECT * FROM CTE_P UNION
        SELECT * FROM CTE_MODEL UNION
        SELECT * FROM CTE_AREA
    ) t
    ORDER BY
        PRODUCT_ID
       ,PRODUCT_VID
       ,ORDER_ID
       ,COL2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...