将两个表+第三个表连接为条件列

时间:2017-11-25 22:51:21

标签: sql database postgresql

如果我有三个名为warehousewarehouse_order的表和名为warehouse_fulfillment的表。仓库管理员创建仓库订单,最初有0个履行记录,可以有许多warehouse_fulfillment个记录,其中包含失败/拒绝状态,只有一个成功状态(已完成):

-- Warehouse
+---------------------------------------+-----------+----------+
| id                                    | name      | location |
+---------------------------------------+-----------+----------+
| 9bcae08e-ad36-4d97-b9ec-4857714e902a  | "big"     | "MLB"    |
+---------------------------------------+-----------+----------+
| b442e783-4725-41e9-af83-f75004ee1b38  | "bigger"  | "MLB"    |
+---------------------------------------+-----------+----------+
| 986d5aa9-0523-42d8-b183-dfd546d3e682  | "biggest" | "MLB"    |
+---------------------------------------+-----------+----------+


-- Warehouse_order Table
+---------------------------------------+--------------------------------------+--------+----------+
| id                                    | warehouse_id                         |  type  | quantity |
+---------------------------------------+--------------------------------------+--------+----------+
| 9cb99fd9-9e5e-4240-8162-d28747be01cd  | b442e783-4725-41e9-af83-f75004ee1b38 | BN_100 | 100      |
+---------------------------------------+-------------------------------------+--------+-----------+
| eceb0b5a-5afa-40e4-ac62-efb686e3bdae  | 9bcae08e-ad36-4d97-b9ec-4857714e902a | BN_200 | 400      |
+---------------------------------------+--------------------------------------+--------+----------+
| 13370467-cf0c-47f2-8fea-a215500607e6  | 986d5aa9-0523-42d8-b183-dfd546d3e68  | BN_300 | 10       |
+---------------------------------------+--------------------------------------+--------+----------+


-- Warhouse_fulfillment Table
+---------------------------------------+---------------------------------------+------------+
| id                                    | order_id                              | status     |
+---------------------------------------+---------------------------------------+------------+
| 8a69edde-2346-48b8-96d0-6c4e25527f38  | 9cb99fd9-9e5e-4240-8162-d28747be01cd  | "FAILLED"  |
+---------------------------------------+---------------------------------------+------------+
| a2006a64-9bdc-4bfa-ba14-a44769aeb4a2  | 9cb99fd9-9e5e-4240-8162-d28747be01cd  | "REJECTED" |
+---------------------------------------+---------------------------------------+------------+
| bf0aa1fc-6dfc-4fd0-ba20-be101b1985d1  | 9cb99fd9-9e5e-4240-8162-d28747be01cd  | "FAILED"   |
+---------------------------------------+---------------------------------------+------------+
| 48c7d747-2f9b-4535-8f27-210a43cf5c30  | 9cb99fd9-9e5e-4240-8162-d28747be01cd  | "SUCCESS"  |
+---------------------------------------+---------------------------------------+------------+
| 7f8e18c9-4322-428a-9370-9ecd1c5ef286 |  13370467-cf0c-47f2-8fea-a215500607e6  | "FAILED"   |
+---------------------------------------+---------------------------------------+------------+

我想以这样的方式查询上述记录:结果如下:

+--------------------------------------+-----------+----------+---------------------------------------+------------+----------------+--------------------------------------+
| id                                   | name      | location | order_id                              | order_type | order_quantity | fulfillment_id                       |
+--------------------------------------+-----------+----------+---------------------------------------+------------+----------------+--------------------------------------+
| 9bcae08e-ad36-4d97-b9ec-4857714e902a | "big"     | "MLB"    | eceb0b5a-5afa-40e4-ac62-efb686e3bdae  | "BN_100"   | 100            | NULL                                 |
+--------------------------------------+-----------+----------+---------------------------------------+------------+----------------+--------------------------------------+
| b442e783-4725-41e9-af83-f75004ee1b38 | "bigger"  | "MLB"    | 9cb99fd9-9e5e-4240-8162-d28747be01cd  | "BN_200"   | 400            | 48c7d747-2f9b-4535-8f27-210a43cf5c30 |
+--------------------------------------+-----------+----------+---------------------------------------+------------+----------------+--------------------------------------+
| 986d5aa9-0523-42d8-b183-dfd546d3e682 | "biggest" | "MLB"    | 13370467-cf0c-47f2-8fea-a215500607e6  | "BN_300"   | 10             | NULL                                 |
+--------------------------------------+-----------+----------+---------------------------------------+------------+----------------+--------------------------------------+

在订单有多个失败状态的情况下,如果没有重复的行,我就无法做到这一点。

2 个答案:

答案 0 :(得分:0)

您尝试过SELECT DISTINCT吗?因为您没有选择列表中的状态列(导致重复项),所以这应该有效。

ethertype

否则,我需要知道SQL的用途是什么,但我使用的每种风格都有一些方法可以用分区对结果进行排序/排序,这样你就可以根据某些键获取第一条记录,例如:

version

最好按日期DESC或类似的顺序排序以获取最新记录。

答案 1 :(得分:0)

如果在履行表中没有一些可靠的方法来确定"最新状态",例如时间戳,则需要选择一些任意方法来获得可能状态值中的优先级顺序。下面我在case expression中使用了over clause,以便"成功"如果订单存在该状态,则将获得第1行。根据您认为适合该列的其他可能值来调整案例表达式。

当包含行号的子查询加入到包含and rn=1的连接的主查询时,每个订单只能实现一个履行行。

请注意,在示例数据中有一个缺少的仓库行,所以我不得不使用左连接,但我希望它是真实数据库中的内连接。

SQL Fiddle Demo

CREATE TABLE Warehouse
    (ID varchar(36), Name varchar(9), Location varchar(5))
;

INSERT INTO Warehouse
    ("id", "name", "location")
VALUES
    ('9bcae08e-ad36-4d97-b9ec-4857714e902a', 'big', 'MLB'),
    ('b442e783-4725-41e9-af83-f75004ee1b38', 'bigger', 'MLB'),
    ('986d5aa9-0523-42d8-b183-dfd546d3e682', 'biggest', 'MLB')
;


CREATE TABLE Warehouse_order 
    (ID varchar(36), Warehouse_id varchar(36), type varchar(6), quantity int)
;

INSERT INTO Warehouse_order 
    ("id", "warehouse_id", "type", "quantity")
VALUES
    ('9cb99fd9-9e5e-4240-8162-d28747be01cd', 'b442e783-4725-41e9-af83-f75004ee1b38', 'BN_100', 100),
    ('eceb0b5a-5afa-40e4-ac62-efb686e3bdae', '9bcae08e-ad36-4d97-b9ec-4857714e902a', 'BN_200', 400),
    ('13370467-cf0c-47f2-8fea-a215500607e6', '986d5aa9-0523-42d8-b183-dfd546d3e68', 'BN_300', 10)
;


CREATE TABLE Warehouse_fulfillment 
    (ID varchar(36), Order_id varchar(36), Status varchar(10))
;


INSERT INTO Warehouse_fulfillment 
    ("id", "order_id", "status")
VALUES
    ('8a69edde-2346-48b8-96d0-6c4e25527f38', '9cb99fd9-9e5e-4240-8162-d28747be01cd', 'FAILLED'),
    ('a2006a64-9bdc-4bfa-ba14-a44769aeb4a2', '9cb99fd9-9e5e-4240-8162-d28747be01cd', 'REJECTED'),
    ('bf0aa1fc-6dfc-4fd0-ba20-be101b1985d1', '9cb99fd9-9e5e-4240-8162-d28747be01cd', 'FAILED'),
    ('48c7d747-2f9b-4535-8f27-210a43cf5c30', '9cb99fd9-9e5e-4240-8162-d28747be01cd', 'SUCCESS'),
    ('7f8e18c9-4322-428a-9370-9ecd1c5ef286', '13370467-cf0c-47f2-8fea-a215500607e6', 'FAILED')
;

查询1

select
     o.*, w.name, s.status, s.rn
from Warehouse_order o
left join Warehouse w on o.Warehouse_id = w.id
left join (
      select id, order_id, status
          , row_number() over(partition by order_id 
                              order by case when status = 'SUCCESS' then 1
                                            when status = 'FAILED' then 2
                                            when status = 'REJECTED' then 3
                                            else 4 end) as rn
      from Warehouse_fulfillment
      ) s on o.id = s.Order_id and rn=1

<强> Results

|                                   id |                         warehouse_id |   type | quantity |   name |  status |     rn |
|--------------------------------------|--------------------------------------|--------|----------|--------|---------|--------|
| eceb0b5a-5afa-40e4-ac62-efb686e3bdae | 9bcae08e-ad36-4d97-b9ec-4857714e902a | BN_200 |      400 |    big |  (null) | (null) |
| 9cb99fd9-9e5e-4240-8162-d28747be01cd | b442e783-4725-41e9-af83-f75004ee1b38 | BN_100 |      100 | bigger | SUCCESS |      1 |
| 13370467-cf0c-47f2-8fea-a215500607e6 |  986d5aa9-0523-42d8-b183-dfd546d3e68 | BN_300 |       10 | (null) |  FAILED |      1 |