【问题标题】:Get columns from joined tables as rows instead of adjacent columns从连接表中获取列作为行而不是相邻列
【发布时间】:2019-06-26 12:14:21
【问题描述】:

我有三个表 A_PRODUCT、A_MODEL 和 A_AREA。可以使用 PRODUCT_ID 连接这些表。我想得到一个输出,使得 A_PRODUCT 表中的一行后面是 A_MODEL 表中的行,然后是 A_AREA 表中的行。以下是创建示例数据的 SQL:

CREATE TABLE A_PRODUCT
(
PRODUCT_ID NVARCHAR(30),
PODUCT_NAME NVARCHAR(30),
);

INSERT INTO A_PRODUCT (PRODUCT_ID, PODUCT_NAME)
VALUES ('P-1', 'LONG-SLEEVE LOGO JERSEY');

INSERT INTO A_PRODUCT (PRODUCT_ID, PODUCT_NAME)
VALUES ('P-2', 'GLASSES');


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

INSERT INTO A_MODEL (MODEL_ID, MODEL_NAME, PRODUCT_ID)
VALUES ('M-1', 'OLD JERSEY', 'P-1');

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

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

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|LONG-SLEEVE LOGO JERSEY|
|MODEL|M-1|OLD JERSEY|
|AREA|A-1|SOUTH|
|AREA|A-2|NORTH|
|AREA|A-3|EAST|
|AREA|A-4|WEST|
|PRODUCT|P-2|GLASSES|
|MODEL|M-2|RAY-BAN|
|MODEL|M-3|ARMANI|
|AREA|A-5|SOUTH-WEST|

我尝试了以下查询,但它没有给我想要的输出:

;WITH CTE AS 
(
SELECT CONCAT('|PRODUCT|', P.PRODUCT_ID,'|',P.PODUCT_NAME,'|') AS Col1,
        CONCAT('|MODEL|', M.MODEL_ID,'|',M.MODEL_NAME,'|') AS COl2,
        CONCAT('|AREA|', A.AREA_ID,'|',A.AREA_NAME,'|') AS COl3      
    FROM A_PRODUCT P
    JOIN A_MODEL M
    ON P.PRODUCT_ID = M.PRODUCT_ID
    JOIN A_AREA A
    ON P.PRODUCT_ID = A.PRODUCT_ID
 )
 SELECT Result
 FROM CTE
 CROSS APPLY (VALUES (Col1,'Col1'),(Col2,'Col2'),(Col3,'Col3')
              )DT (Result,Names);

【问题讨论】:

  • 您希望您的行按特定顺序返回,但您解决问题的尝试却没有在任何地方使用 ORDER BY?为什么?
  • 抱歉,我忘记在示例查询中输入 order by,但是,由于我得到的行是重复的,它不会给我所需的输出。
  • 我认为你想要一个 UNION 而不是一个联接!

标签: sql sql-server join


【解决方案1】:

你真的不想在这里JOIN。您需要使用PRODUCT_IDUNION 的结果进行排序,并且您需要根据信息来自的表强制进行额外的排序。

使用子查询以您需要的方式对数据进行分组,使用外部 SELECT 获取导出数据所需的格式。

SELECT
  CONCAT('|',d.DetailCol1,'|',d.DetailCol2,'|', d.DetailCol3,'|') AS DelimitedList
FROM
  (
    SELECT
      PRODUCT_ID AS SortCol1,
      1 AS SortCol2,
      'PRODUCT' AS DetailCol1,
      PRODUCT_ID AS DetailCol2,
      PRODUCT_NAME AS DetailCol3
    FROM @A_PRODUCT
    UNION ALL
    SELECT
      PRODUCT_ID AS SortCol1,
      2 AS SortCol2,
      'MODEL' AS DetailCol1,
      MODEL_ID AS DetailCol2,
      MODEL_NAME AS DetailCol3
    FROM @A_MODEL
    UNION ALL
    SELECT
      PRODUCT_ID AS SortCol1,
      3 AS SortCol2,
      'AREA' AS DetailCol1,
      AREA_ID AS DetailCol2,
      AREA_NAME AS DetailCol3
    FROM @A_AREA
  ) AS d
ORDER BY 
  d.SortCol1,
  d.SortCol2;
+---------------------------------------+
|             DelimitedList             |
+---------------------------------------+
| |PRODUCT|P-1|LONG-SLEEVE LOGO JERSEY| |
| |MODEL|M-1|OLD JERSEY|                |
| |AREA|A-1|SOUTH|                      |
| |AREA|A-2|NORTH|                      |
| |AREA|A-3|EAST|                       |
| |AREA|A-4|WEST|                       |
| |PRODUCT|P-2|GLASSES|                 |
| |MODEL|M-2|RAY-BAN|                   |
| |MODEL|M-3|ARMANI|                    |
| |AREA|A-5|SOUTH-WEST|                 |
+---------------------------------------+

【讨论】:

  • 谢谢埃里克。这是在样本数据集中提供所需的输出。但是实际场景三张表列多,列数不匹配。另外,因为选择数据的条件不在一列上,所以需要JOIN。
  • @OraAff 每当您发布带有示例数据的问题时,有人给出的答案解决了您的示例数据问题,而该解决方案不适用于您的真实数据,这意味着您有发布您的问题做得不好。您可能应该将此标记为答案并发布一个新问题,其中包含更好地代表实际数据的所有复杂性的示例数据。
  • 我正准备将其标记为已回答。只是忙于在实际场景中进行拟合。
【解决方案2】:

您可以使用以下查询来获得所需的输出-

SELECT '| PRODUCT | '+PRODUCT_ID+' | '+PODUCT_NAME +' |' FROM A_PRODUCT
UNION ALL
SELECT '| AREA | '+AREA_ID+' | '+AREA_NAME +' |' FROM A_AREA
UNION ALL
SELECT '| MODEL | '+MODEL_ID+' | '+MODEL_NAME +' |' FROM A_MODEL

输出是-(如果需要,您可以删除值之间的空格)

| PRODUCT | P-1 | LONG-SLEEVE LOGO JERSEY |
| PRODUCT | P-2 | GLASSES |
| AREA | A-1 | SOUTH |
| AREA | A-2 | NORTH |
| AREA | A-3 | EAST |
| AREA | A-4 | WEST |
| AREA | A-5 | SOUTH-WEST |
| MODEL | M-1 | OLD JERSEY |
| MODEL | M-2 | RAY-BAN |
| MODEL | M-3 | ARMANI |

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-29
    • 2018-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-30
    相关资源
    最近更新 更多