gpt4 book ai didi

sql - 从自连接计算

转载 作者:行者123 更新时间:2023-11-29 09:21:09 24 4
gpt4 key购买 nike

我有一个股票代码的值和日期列表,并且想要用 SQL 计算季度返回。

CREATE TABLE `symbol_details` (
`symbol_header_id` INT(11) DEFAULT NULL,
`DATE` DATETIME DEFAULT NULL,
`NAV` DOUBLE DEFAULT NULL,
`ADJ_NAV` DOUBLE DEFAULT NULL)

对于固定的季度开始和结束日期效果很好:

set @quarterstart='2008-12-31';
set @quarterend='2009-3-31';

select sha, (100*(aend-abegin)/abegin) as q1_returns from
(select symbol_header_id as sha, ADJ_NAV as abegin from symbol_details
where date=@quarterstart) as a,
(select symbol_header_id as she, ADJ_NAV as aend from symbol_details
where date=@quarterend) as b
where sha=she;

这将计算所有代码的所有季度返回。有时季度末是非交易日,或者股票停止运营,所以我想获得与季度开始和结束日期最接近的开始和结束日期。

解决方案是以某种方式通过某些 GROUP BY 语句仅获取每个 symbol_header_id 的一个开始和一个季度结束值,例如 (1)

SET @quarterstart = '2009-03-01';
SET @quarterend = '2009-4-31';
SELECT symbol_header_id, DATE, ADJ_NAV AS aend FROM symbol_details
WHERE
DATE BETWEEN @quarterstart AND @quarterend
AND symbol_header_id BETWEEN 18540 AND 18550
GROUP BY symbol_header_id asc;

这给出了每个 symbol_header_id 值最接近季度开始日期的 ADJ_NAV 值。

最后,(2)

SET @quarterstart = '2008-12-31';
SET @quarterend = '2009-3-31';

SELECT sh1, a.date, b.date, aend, abegin,
(100*(aend-abegin)/abegin) AS quarter_returns FROM
(SELECT symbol_header_id sh1, DATE, ADJ_NAV AS abegin FROM symbol_details
WHERE
DATE BETWEEN @quarterstart AND @quarterend
GROUP BY symbol_header_id DESC) a,

(SELECT symbol_header_id sh2, DATE, ADJ_NAV AS aend FROM symbol_details
WHERE
DATE BETWEEN @quarterstart AND @quarterend
GROUP BY symbol_header_id ASC) b
WHERE sh1 = sh2;

应计算每个交易品种的季度返回。

不幸的是,这不起作用。由于某种原因,当我像 (1) 那样限制 ID 时,会使用正确的开始日期和结束日期,但是当删除“AND symbol_header_id BETWEEN 18540 AND 18550”语句时,会出现相同的开始日期和结束日期。为什么???

展开 JOIN 的答案是:

SET @quarterstart = '2008-12-31';
SET @quarterend = '2009-3-31';


SELECT tq.sym AS sym,
(100*(alast.adj_nav - afirst.adj_nav)/afirst.adj_nav) AS quarterly_returns
FROM

-- First, determine first traded days ("ftd") and last traded days
-- ("ltd") in this quarter per symbol
(SELECT symbol_header_id AS sym,
MIN(DATE) AS ftd,
MAX(DATE) AS ltd
FROM symbol_details
WHERE DATE BETWEEN @quarterstart AND @quarterend
GROUP BY 1) tq

JOIN symbol_details afirst
-- Second, determine adjusted NAV for "ftd" per symbol (see WHERE)
ON afirst.DATE BETWEEN @quarterstart AND @quarterend
AND afirst.symbol_header_id = tq.sym

JOIN
-- Finally, determine adjusted NAV for "ltd" per symbol (see WHERE)
symbol_details alast
ON alast.DATE BETWEEN @quarterstart AND @quarterend
AND alast.symbol_header_id = tq.sym

WHERE
afirst.date = tq.ftd
AND
alast.date = tq.ltd;

最佳答案

更新:

合并@ Hogan的建议完全......并进行测试。 :) 这个 EXPLAIN 更简单,并且应该表现得更好。

再次假设 ANSI_QUOTES 行为:

SELECT tq.sym AS sym,
(100*(alast.adj_nav - afirst.adj_nav)/afirst.adj_nav) AS quarterly_returns
FROM
(SELECT symbol_header_id AS sym, -- find first/last traded day ("ftd", "ltd")
MIN("date") AS ftd,
MAX("date") AS ltd
FROM symbol_details
WHERE "date" BETWEEN @quarterstart AND @quarterend
GROUP BY 1) tq
JOIN symbol_details afirst -- JOIN for ADJ_NAV on first traded day
ON tq.sym = afirst.symbol_header_id
AND
tq.ftd = afirst."date"
JOIN symbol_details alast -- JOIN for ADJ_NAV on last traded day
ON tq.sym = alast.symbol_header_id
AND
tq.ltd = alast."date"

原件:

假设SET SESSION sql_mode = 'ANSI_QUOTES',试试这个:

SELECT tq.sym                                AS sym,
(100*(adj_end - adj_begin)/adj_begin) AS quarterly_returns
FROM
-- First, determine first traded days ("ftd") and last traded days
-- ("ltd") in this quarter per symbol
(SELECT symbol_header_id AS sym,
MIN("date") AS ftd,
MAX("date") AS ltd
FROM symbol_details
WHERE "date" BETWEEN @quarterstart AND @quarterend
GROUP BY 1) tq
JOIN
-- Second, determine adjusted NAV for "ftd" per symbol (see WHERE)
(SELECT symbol_header_id AS sym,
"date" AS adate,
adj_nav AS adj_begin
FROM symbol_details) afirst
ON afirst.sym = tq.sym
JOIN
-- Finally, determine adjusted NAV for "ltd" per symbol (see WHERE)
(SELECT symbol_header_id AS sym,
"date" AS adate,
adj_nav AS adj_end
FROM symbol_details) alast
ON alast.sym = tq.sym
WHERE
afirst.adate = tq.ftd
AND
alast.adate = tq.ltd;

关于sql - 从自连接计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1780372/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com