繁体   English   中英

postgres function:传递并遍历数组

[英]postgres function: pass and iterate through array

我不知道我正在尝试做的事情是否可能在 PostgreSQL 中。 但是在这里我们 go:我想将字符串数组传递给 function。 然后我想遍历这个数组,并想从基于当前字符串的表中SELECT数据。

选择的数据应该被推送到一个新的数组(或表?),当迭代完成时返回。

这是我在 JavaScript 中尝试做的简化版本:

const symbols = ["PAM", "EVC", "BIBI", "AA"];

const getLatestQuotes = (tickerSymbols) => {
  const dataToReturn = [];
  tickerSymbols.forEach((symbol) => {
    // do something with symbol
    const newVal = "bla bla" + symbol;

    dataToReturn.push(newVal);
  });

  return dataToReturn;
};

const quotes = getLatestQuotes(symbols);

console.log("quotes", quotes);

编辑:这是我到目前为止所拥有的 SQL:

CREATE OR REPLACE FUNCTION get_latest_quotes
(
    ArrayText character varying[]
)
RETURNS TABLE (ticker VARCHAR(10), quotetime text, price text) AS
$BODY$
DECLARE
    Counter INT = 0 ;
BEGIN
    CREATE TEMP TABLE ArrayData(ticker VARCHAR(10), quotetime text, price text);
    FOR Counter in array_lower(ArrayText, 1) .. array_upper(ArrayText, 1)
    LOOP
        INSERT INTO ArrayData VALUES(
      SELECT ticker, quotetime, price FROM quotes WHERE ticker = ArrayText[Counter];
    );
    END LOOP;

    RETURN QUERY
    SELECT ArrayTextData
    FROM ArrayData;

    DISCARD TEMP;
END;
$BODY$
LANGUAGE plpgsql VOLATILE;

我希望这种解释我正在尝试做的事情。

EDIT2:谢谢@a_horse_with_no_name,这很有帮助。 不过还有一个问题。 我回来的样子是这样的:

{ ticker: 'AAPL', timestamp: '934934400', price: 0.54000002145767 },
{ ticker: 'AAPL', timestamp: '935020800', price: 0.51999998092651 },
{ ticker: 'AAPL', timestamp: '935107200', price: 0.52999997138977 },
{ ticker: 'AAPL', timestamp: '935366400', price: 0.54000002145767 },
{ ticker: 'AAPL', timestamp: '935452800', price: 0.54000002145767 },
{ ticker: 'AAPL', timestamp: '935539200', price: 0.55000001192093 },
.
.
.
{ ticker: 'MSFT', timestamp: '934848000', price: 0.54000002145767 },
{ ticker: 'MSFT', timestamp: '934934400', price: 0.54000002145767 },
{ ticker: 'MSFT', timestamp: '935020800', price: 0.51999998092651 },
{ ticker: 'MSFT', timestamp: '935107200', price: 0.52999997138977 },
{ ticker: 'MSFT', timestamp: '935366400', price: 0.54000002145767 },
{ ticker: 'MSFT', timestamp: '935452800', price: 0.54000002145767 },
{ ticker: 'MSFT', timestamp: '935539200', price: 0.55000001192093 },
.
.
.
{ ticker: 'GOOGL', timestamp: '934848000', price: 0.54000002145767 },
{ ticker: 'GOOGL', timestamp: '934934400', price: 0.54000002145767 },
{ ticker: 'GOOGL', timestamp: '935020800', price: 0.51999998092651 },
{ ticker: 'GOOGL', timestamp: '935107200', price: 0.52999997138977 },
{ ticker: 'GOOGL', timestamp: '935366400', price: 0.54000002145767 },
{ ticker: 'GOOGL', timestamp: '935452800', price: 0.54000002145767 },
{ ticker: 'GOOGL', timestamp: '935539200', price: 0.55000001192093 },

现在,我只想要具有最新时间戳的每个股票代码的行。 我怎么能用 SQL 做到这一点?

编辑3:

我已经设法弄清楚(几乎):

CREATE OR REPLACE FUNCTION get_latest_quotes(ArrayText character varying[])
  RETURNS TABLE (ticker VARCHAR(10), "timestamp" int8, price float8) AS
$BODY$
  SELECT ticker, timestamp, price 
  FROM base.quotes 
  WHERE ticker = any(arraytext) 
  ORDER BY timestamp DESC
  LIMIT 10;
$BODY$
LANGUAGE sql
stable;

这几乎是我想要的。 这就是它给我的:

AAPL    1615901400  123.99
MSFT    1615901400  234.81
RIO.AX  1615852800  114.13
AAPL    1615838402  123.99

如您所见, FB丢失了,因为它的时间戳比 AAPL 旧。 我怎样才能告诉 SQL 我只想要我通过的每个股票代码的一行?

为此,您不需要循环、临时表甚至 PL/pgSQL。

这可以通过单个查询来实现:

CREATE OR REPLACE FUNCTION get_latest_quotes(ArrayText character varying[])
  RETURNS TABLE (ticker VARCHAR(10), quotetime text, price text) AS
$BODY$
  SELECT ticker, quotetime, price 
  FROM quotes 
  WHERE ticker = any(arraytext);
$BODY$
LANGUAGE sql
stable;

您可以像使用表格一样使用 function:

select *
from get_latest_quotes(array['PAM', 'EVC', 'BIBI', 'AA']);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM