PostgreSQL子查询拆分行(错误是由用作表达式的子查询返回的多行)

时间:2016-06-22 17:59:23

标签: postgresql

这是我在stackoverflow上的第一篇文章,所以请保持温和。我已经研究过这个问题并提出了许多不同的解决方案......所有这些解决方案似乎都与我的需求完全不同。我在SELECT语句中有一个postgresql子查询,它返回多行,我知道这显然不是理想/允许/敏感/等等....但是,这是我当前问题的情况,我需要能够采取这些多个返回的行并将它们应用于它们最初出现的每个先前对应的记录行。

当前查询:

SELECT cohead_number "Sales Order#",
       cohead_custponumber "Purchase Order#",
       item_number "Part Number",
       item_descrip1 "Part Description",
       CAST(shipitem_qty AS integer) "Item Quantity",
       getPacklistItemLotSerial(shiphead_id, coitem_id) AS "LotNumbers"  --this is the duplicating row subquery that I need listed in separate rows without changing other respective columns--
FROM   cohead
       LEFT JOIN coitem
              ON coitem_cohead_id = cohead_id
       LEFT JOIN shipitem
              ON coitem_id = shipitem_orderitem_id
       LEFT JOIN itemsite
              ON coitem_itemsite_id = itemsite_id
       LEFT JOIN item
              ON itemsite_item_id = item_id
       LEFT JOIN shiphead
              ON shiphead_order_id = cohead_id
WHERE cohead_number = '79464' --this is just to test with one sales order instead of all (sales order being the input for the query)--

结果:

LINK: Results of above query here

我尝试过什么

现在,这一行让我可以通过分隔符'来分割列结果。但我无法弄清楚如何将结果反馈到原始查询的结果中:

(SELECT lot from regexp_split_to_table(getPacklistItemLotSerial(shiphead_id, coitem_id),', ') AS lot)

结果:

在这里,我为示例销售订单输入shiphead_id和coitem_id,以便它可以将生成的拆分列显示为行。

  

从regexp_split_to_table中选择批次(getPacklistItemLotSerial(22082,50351),',')AS lot

LINK: Results of Example

请帮助我完成我需要做的事情来实现这一目标。我成像我们需要声明一些东西,并且可能在一个更复杂的查询中加入2个表...我真的不知道。感谢您提供任何帮助。

修改

在函数" getpacklistitemlotserial"

的请求源代码中添加
DECLARE
  pShipheadId ALIAS FOR $1;
  pOrderItemId ALIAS FOR $2;
  _lotserial text;
  _r RECORD;
  _first BOOLEAN;

BEGIN

  --Test to see if Lot/Serial Enabled
  SELECT metric_value INTO _lotserial
  FROM metric
  WHERE ((metric_name='LotSerialControl')
  AND (metric_value ='t'));

  IF (FOUND) THEN
    _lotserial := '';
    _first := true;

    FOR _r IN SELECT DISTINCT ls_number
              FROM invdetail, invhist, shipitem, ls
             WHERE ((shipitem_shiphead_id=pShipheadId)
               AND  (shipitem_orderitem_id=pOrderItemId)
               AND  (shipitem_invhist_id=invhist_id)
               AND  (invhist_id=invdetail_invhist_id)
               AND  (invdetail_ls_id=ls_id)) LOOP
      IF (_first = false) THEN
        _lotserial := _lotserial || ', ';
      END IF;
      _lotserial := _lotserial || _r.ls_number;
      _first := false;
    END LOOP;

    RETURN _lotserial;
  ELSE
    RETURN '';
  END IF;

END

1 个答案:

答案 0 :(得分:0)

尝试:

SELECT DISTINCT cohead_number "Sales Order#",
       cohead_custponumber "Purchase Order#",
       item_number "Part Number",
       item_descrip1 "Part Description",
       CAST(shipitem_qty AS integer) "Item Quantity",
      --  getPacklistItemLotSerial(shiphead.shiphead_id, coitem.coitem_id) AS "LotNumbers"  --this is the duplicating row subquery that I need listed in separate rows without changing other respective columns--
       CASE WHEN EXISTS(  
                 SELECT metric_value FROM metric
                 WHERE metric_name='LotSerialControl' AND metric_value ='t'
            )
            THEN x.ls_number
            ELSE ''
        END AS "LotNumbers"
FROM   cohead
       LEFT JOIN coitem
              ON coitem_cohead_id = cohead_id
       LEFT JOIN shipitem
              ON coitem_id = shipitem_orderitem_id
       LEFT JOIN itemsite
              ON coitem_itemsite_id = itemsite_id
       LEFT JOIN item
              ON itemsite_item_id = item_id
       LEFT JOIN shiphead
              ON shiphead_order_id = cohead_id
       LEFT JOIN (
            SELECT ls_number,
                   shipitem_shiphead_id, -- parameter: pShipheadId 
                   shipitem_orderitem_id -- parameter pOrderItemId
              FROM invdetail, invhist, shipitem, ls
             WHERE 
               -- (shipitem_shiphead_id=pShipheadId)
               -- AND  (shipitem_orderitem_id=pOrderItemId)
               (shipitem_invhist_id=invhist_id)
               AND  (invhist_id=invdetail_invhist_id)
               AND  (invdetail_ls_id=ls_id)
       ) x
       ON ( x.shipitem_shiphead_id = shiphead.shiphead_id
            AND
            x.shipitem_orderitem_id = coitem.coitem_id
       )
WHERE cohead_number = '79464'