2 tables - Select 来自不同 table 的一行,当列值更改时

2 tables - Select a row from different table when column value changes

这是在 MS SSMS 2016 中。我有两个表 - SHIPMENT_HEADER 和 SHIPMENT_DETAIL。

SHIPMENT_HEADER

shipment_id |  customer  | 
------------|------------|
SH001       |    cust1   |
SH002       |    cust2   |

Shipment_detail 有相似的列

SHIPMENT_DETAIL

shipment_id | customer | item   | requested_qty|
------------|----------|--------|--------------|
SH001       |   cust1  |  item1 |    2         |
SH001       |   cust1  |  item2 |    2         |
SH001       |   cust1  |  item3 |    1         |
SH002       |   cust2  |  item1 |    2         |
SH002       |   cust2  |  item2 |    2         |

我想知道是否有可能写一些东西,以便对于每个 shipment_id,它 returns shipment_header 详细信息,下面列出 shipment_details , 所以:

shipment_id | instruction  |customer | item   | requested_qty|
------------|--------------|---------|--------|--------------|
SH001       |    HEADER    |  cust1  |  NULL  |    5         |
SH001       |    DETAIL    |  cust1  |  item1 |    2         |
SH001       |    DETAIL    |  cust1  |  item2 |    2         |
SH001       |    DETAIL    |  cust1  |  item3 |    1         |
SH002       |    HEADER    |  cust2  |  NULL  |    4         |
SH002       |    DETAIL    |  cust2  |  item1 |    2         |
SH002       |    DETAIL    |  cust2  |  item2 |    2         |

我想可能是 select 和 header 的 UNION,然后是详细信息,但是如果我一次查询多个货件,它 select 就是 header然后是所有详细信息,而不是 header-details、header-details.

到目前为止,我所拥有的基本上只是 select 分别对每一位进行处理。这是在考虑 UNION 的情况下编写的,因此如果使用其他方法,则可能不需要某些 NULL 列

SELECT
SH.SHIPMENT_ID 'SHIPMENT_ID', 
'HEADER' AS 'INSTRUCTION_TYPE',
SH.CUSTOMER 'CUSTOMER', 
NULL 'ITEM',
B.TOTAL_QTY
FROM SHIPMENT_HEADER SH
    INNER JOIN (
    SELECT SHIPMENT_ID, SUM(REQUESTED_QTY) 'TOTAL_QTY'
    FROM SHIPMENT_DETAIL
    GROUP BY SHIPMENT_ID
    ) AS B
ON SH.SHIPMENT_ID = B.SHIPMENT_ID
WHERE SH.SHIPMENT_ID IN ('SH001','SH002')
UNION
SELECT 
SD.SHIPMENT_ID,
'SHIPMENT_DETAIL' AS 'INSTRUCTION_TYPE',
SD.CUSTOMER,
SD.ITEM,
SD.REQUESTED_QTY
FROM SHIPMENT_DETAIL SD
WHERE SD.SHIPMENT_ID IN (
'SH001', 'SH002'
)
ORDER BY 1, 2

试试这个。在这里,我假设对于 shipment_id 你有相同的 customer,按照你的例子。如果不是这种情况,您必须告诉 customer 您想要用 HEADER 记录显示。

编辑:使用 CTE 仅考虑 SHIPMENT_HEADERSHIPMENT_DETAIL 中的记录。

with t_SHIPMENT_DETAIL as
(SELECT d.shipment_id,
               d.customer,
               d.item,
               d.requested_qty
       FROM SHIPMENT_DETAIL d
       inner join
       SHIPMENT_HEADER h
        on d.shipment_id=h.shipment_id
)
SELECT *
FROM
  ( SELECT shipment_id,
           'HEADER' AS instruction,
           customer,
           NULL AS item,
           sum(requested_qty) AS requested_qty
   FROM t_SHIPMENT_DETAIL
   GROUP BY shipment_id,
            customer

   UNION ALL 

   SELECT shipment_id,
            'DETAIL' AS instruction,
            customer,
            item,
            requested_qty
   FROM t_SHIPMENT_DETAIL 
   )
ORDER BY shipment_id,
         instruction DESC

说明:联合中的第一个查询是根据 shipment_id, customer 获取 sum(requested_qty) 组。我们在这里为项目硬编码 HEADERnull。现在 union 的第二部分是您当前的查询装运详细信息,除了额外的列 DETAIL。匹配UNION

中的列

最后,将其封装在 order by 的 select 子句中。

您可以使用以下语句:

(
SELECT header.shipment_id, 'HEADER' as 'instruction', header.customer, NULL as 'item', SUM(requested_qty) as 'requested_qty'
FROM SHIPMENT_HEADER header
LEFT JOIN SHIPMENT_DETAIL detail
ON header.shipment_id = detail.shipment_id
AND header.customer = detail.customer
GROUP BY header.shipment_id, header.customer
)
UNION
(
SELECT shipment_id, 'DETAIL', customer, item, requested_qty
FROM SHIPMENT_DETAIL
)
ORDER BY 1, 2 DESC, 3, 4

结果如下

shipment_id instruction customer   item       requested_qty
----------- ----------- ---------- ---------- -------------
SH001       HEADER      cust1      NULL       5
SH001       DETAIL      cust1      item1      2
SH001       DETAIL      cust1      item2      2
SH001       DETAIL      cust1      item3      1
SH002       HEADER      cust2      NULL       4
SH002       DETAIL      cust2      item1      2
SH002       DETAIL      cust2      item2      2