sql - postgres 函数:传递和遍历数组
问题描述
我不知道我正在尝试做的事情是否在 PostgreSQL 中是可能的。但是我们开始了:我想将一个字符串数组传递给一个函数。然后我想遍历这个数组并想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;
您可以像使用表格一样使用该功能:
select *
from get_latest_quotes(array['PAM', 'EVC', 'BIBI', 'AA']);
推荐阅读
- ckeditor4.x - Adblocker 禁用 CKEditor 4 文本区域,因此无法写入
- python - 获取http状态码
- c# - 没有名为 xlsxwriter.workbook -Ironpython 的模块
- angular - 请为 Angular 6 推荐任何滚动条插件
- javascript - 如何遍历对象数组并获取值
- javascript - 如何根据对象过滤 GeoJson 中的对象?
- java - 如果 columnNames 和 fieldNames 使用 java Reflection 不同,如何将 POJO 与数据库 ResultSet 映射?
- android - 临时存储 JSON 对象并在 Internet 可用时 POST 到 Volley
- spring-mvc - Spring/Thymeleaf 在处理@PostMapping 时抛出“在响应提交后无法创建会话”
- gdb - gdb 调试器不熟悉显示的代码