【问题标题】:Oracle sql - Adding sql row value from one table as column value count to another tableOracle sql - 将一个表中的 sql 行值作为列值计数添加到另一个表中
【发布时间】:2019-03-15 03:51:09
【问题描述】:

我的架构中有以下表和值

CREATE TABLE products
(product_id NUMBER(5) NOT NULL,
 product_name VARCHAR2(10) NOT NULL,
 CONSTRAINT product_pk PRIMARY KEY (product_id)
);

CREATE TABLE packages
(package_id NUMBER(5) NOT NULL,
 package_name VARCHAR2(10) NOT NULL,
 CONSTRAINT package_pk PRIMARY KEY (package_id)
);

CREATE TABLE product_packages
(product_id NUMBER(5) NOT NULL,
 package_id NUMBER(5) NOT NULL,
 CONSTRAINT product_fk FOREIGN KEY (product_id) REFERENCES products(product_id),
 CONSTRAINT package_fk FOREIGN KEY (package_id) REFERENCES packages(package_id)
);

CREATE TABLE customers
(customer_id NUMBER(10) NOT NULL,
 customer_name VARCHAR2(50) NOT NULL,
 CONSTRAINT customer_pk PRIMARY KEY (customer_id)
);

CREATE TABLE orders
(order_id NUMBER(5) NOT NULL,
 customer_id NUMBER(10) NOT NULL,
 product_id NUMBER(5) NOT NULL,
 quantity NUMBER(5) NOT NULL,
 CONSTRAINT ord_customer_fk FOREIGN KEY (customer_id) REFERENCES customers(customer_id),
 CONSTRAINT ord_product_fk FOREIGN KEY (product_id) REFERENCES products(product_id)
);


INSERT  INTO products (product_id, product_name) VALUES (1, 'BARBB');
INSERT  INTO products (product_id, product_name) VALUES (2, 'BARHB');
INSERT  INTO products (product_id, product_name) VALUES (3, 'BARFB');
INSERT  INTO packages (package_id, package_name) VALUES (1, 'BRF');
INSERT  INTO packages (package_id, package_name) VALUES (2, 'LNC');
INSERT  INTO packages (package_id, package_name) VALUES (3, 'DNR');
INSERT  INTO product_packages (product_id, package_id) VALUES (1, 1);
INSERT  INTO product_packages (product_id, package_id) VALUES (2, 1);
INSERT  INTO product_packages (product_id, package_id) VALUES (2, 3);
INSERT  INTO product_packages (product_id, package_id) VALUES (3, 1);
INSERT  INTO product_packages (product_id, package_id) VALUES (3, 2);
INSERT  INTO product_packages (product_id, package_id) VALUES (3, 3);
INSERT  INTO customers (customer_id, customer_name) VALUES (1, 'John Smith');
INSERT  INTO customers (customer_id, customer_name) VALUES (2, 'Adam Nash');
INSERT  INTO orders (order_id, customer_id, product_id, quantity) VALUES (1, 1, 2, 1);
INSERT  INTO orders (order_id, customer_id, product_id, quantity) VALUES (2, 2, 3, 2);

我想要做的是在 PACKAGES 表中使用包名称向 ORDER 表中添加列;如果该产品包含相应的包装,则表示 QUANTITY 列值,否则为 0;结果应该是这样的

ORDER_ID    CUSTOMER_ID PRODUCT_ID  QUANTITY    BRF  LNC    DNR
--------    ----------- ----------  --------    ---  ---    ---
1           1           2           1           1    0      1
2           2           3           2           2    2      2

--更新:新问题 我可以在一张桌子上做多个枢轴吗?就像我将我的 ORDERS 表修改为

CREATE TABLE orders
(order_id NUMBER(5) NOT NULL,
 customer_id NUMBER(10) NOT NULL,
 product_id NUMBER(5) NOT NULL,
 adl_q NUMBER(5) NOT NULL,
 kid_q NUMBER(5),
 CONSTRAINT ord_customer_fk FOREIGN KEY (customer_id) REFERENCES customers(customer_id),
 CONSTRAINT ord_product_fk FOREIGN KEY (product_id) REFERENCES products(product_id)
);

并且当kid_qty 不为零时,这意味着将创建新的相应包名称,并且也可以对它们进行旋转;对于 ORDER 表,如

INSERT  INTO orders (order_id, customer_id, product_id, adl_qty, kid_qty) VALUES (1, 1, 1, 1, 1);
INSERT  INTO orders (order_id, customer_id, product_id, adl_qty, kid_qty) VALUES (2, 2, 2, 2, 1);

你应该得到结果:

ORDER_ID  CUSTOMER_ID  PRODUCT_ID  ADL_Q  KD_Q  BRF LNC  DNR  KDBRF KDLNC KDDNR
--------  ----------- ----------  ------ ----  ---  ---  ---  -----  ----  ----
       1            1          1       1    1    1    0    1     1     0      0
       2            2          2       2    2    1    2    2     1     0      2 

【问题讨论】:

    标签: sql oracle join create-table


    【解决方案1】:

    您可以使用条件聚合(以及pivot)来做到这一点:

    select o.order_id, o.customer_id, o.product_id, 
           sum(case when p.package_name = 'BRF' then o.quantity else 0 end) as brf,
           sum(case when p.package_name = 'LNC' then o.quantity else 0 end) as lnc,
           sum(case when p.package_name = 'DNR' then o.quantity else 0 end) as dnr
    from orders o left join
         product_packages pp
         on o.product_id = pp.product_id left join
         packages p
         on pp.package_id = p.package_id
    group by o.order_id, o.customer_id, o.product_id
    order by o.order_id;
    

    【讨论】:

      【解决方案2】:

      这个pivot 查询对我有用:

      SQL Fiddle demo

      select order_id, customer_id, product_id, 
             nvl(brf, 0) brf, nvl(lnc, 0) lnc, nvl(dnr, 0) dnr
        from orders 
        left join (
          select product_id, package_name 
            from product_packages 
            join packages using (package_id))
          using (product_id) 
        pivot (max(quantity) for package_name in ('BRF' brf, 'LNC' lnc, 'DNR' dnr))
        order by order_id
      

      结果:

      ORDER_ID CUSTOMER_ID PRODUCT_ID        BRF        LNC        DNR
      -------- ----------- ---------- ---------- ---------- ----------
             1           1          2          1          0          1
             2           2          3          2          2          2
      

      【讨论】:

      • 这很好,但我可以像上面更新的问题那样在一张桌子上做多个数据透视
      猜你喜欢
      • 1970-01-01
      • 2019-03-13
      • 2021-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多