Mysql 当存在';表之间没有物理连接
当表之间没有逻辑连接时,我需要帮助编写更优化的SQL查询。我写了一些子查询,但我不满意,因为我重复了几乎相同的子查询两次。Mysql 当存在';表之间没有物理连接,mysql,sql,join,subquery,sql-optimization,Mysql,Sql,Join,Subquery,Sql Optimization,当表之间没有逻辑连接时,我需要帮助编写更优化的SQL查询。我写了一些子查询,但我不满意,因为我重复了几乎相同的子查询两次。 方案如下: create table rate ( rate_date date, value decimal(10,2), multiplier integer, name varchar(3) ); create table amount ( amount decimal(10,2), amount_year date, rate_na
方案如下:
create table rate (
rate_date date,
value decimal(10,2),
multiplier integer,
name varchar(3)
);
create table amount (
amount decimal(10,2),
amount_year date,
rate_name varchar(3)
);
我希望
amount
表中的每个金额都使用rate
表中的乘数和比率值进行计算,如amount/multiplier*rate
。这两个表的共同点是名称(一些代码标识符)和日期。这些数据应该用来收集数据。仅考虑每年金额的最新费率。如果你愿意帮忙,你可以检查一下。那是我的尝试。
select am.amount /
(
select ra.multiplier
from rate ra
where ra.rate_date = (select max(rate_date)
from rate
where year(rate_date) = year(am.amount_year) and name = am.rate_name)
and ra.name = am.rate_name
) * (
select ra.value
from rate ra
where ra.rate_date = (select max(rate_date)
from rate
where year(rate_date) = year(am.amount_year) and name = am.rate_name)
and ra.name = am.rate_name
) as calculated_amount
from amount am;
您的子查询是相同的,因此您可以在一个查询中完成这项工作:
select am.amount /
(select ra.multiplier * ra.value
from rate ra
where ra.rate_date = (select max(rate_date)
from rate
where year(rate_date) = year(am.amount_year) and name = am.rate_name) and ra.name = am.rate_name
)
) as calculated_amount
from amount am;
或者可以用以下措辞:
select am.amount /
(select ra.multiplier * ra.value
from rate ra
where year(ra.rate_date) = year(am.amount_year) and name = am.rate_name
order by ra.rate_date desc
limit 1
) as calculated_amount
from amount am;
如果愿意,您可以使用where
子句作为join
执行此操作:
select (am.amount / ra.multiplier * ra.value) as calculated_amount
from amount am join
rate ra
on ra.name = am.name and
year(rate_date) = year(am.amount_year)
where ra.date = (select max(r2.rate_date)
from rate r2
where year(r2.rate_date) = year(r.rate_date) and
r2.name = ra.name
);
对于性能,从速率(名称、速率、日期、乘数、值)
上的索引开始。对于这两个查询
为了获得更好的性能,您可能需要将“year”作为一个单独的列存储在表中。您的子查询是相同的,因此您可以在一个表中完成这项工作:
select am.amount /
(select ra.multiplier * ra.value
from rate ra
where ra.rate_date = (select max(rate_date)
from rate
where year(rate_date) = year(am.amount_year) and name = am.rate_name) and ra.name = am.rate_name
)
) as calculated_amount
from amount am;
或者可以用以下措辞:
select am.amount /
(select ra.multiplier * ra.value
from rate ra
where year(ra.rate_date) = year(am.amount_year) and name = am.rate_name
order by ra.rate_date desc
limit 1
) as calculated_amount
from amount am;
如果愿意,您可以使用where
子句作为join
执行此操作:
select (am.amount / ra.multiplier * ra.value) as calculated_amount
from amount am join
rate ra
on ra.name = am.name and
year(rate_date) = year(am.amount_year)
where ra.date = (select max(r2.rate_date)
from rate r2
where year(r2.rate_date) = year(r.rate_date) and
r2.name = ra.name
);
对于性能,从速率(名称、速率、日期、乘数、值)
上的索引开始。对于这两个查询
为了获得更好的性能,您可能需要将“year”作为一个单独的列存储在表中。您的子查询是相同的,因此您可以在一个表中完成这项工作:
select am.amount /
(select ra.multiplier * ra.value
from rate ra
where ra.rate_date = (select max(rate_date)
from rate
where year(rate_date) = year(am.amount_year) and name = am.rate_name) and ra.name = am.rate_name
)
) as calculated_amount
from amount am;
或者可以用以下措辞:
select am.amount /
(select ra.multiplier * ra.value
from rate ra
where year(ra.rate_date) = year(am.amount_year) and name = am.rate_name
order by ra.rate_date desc
limit 1
) as calculated_amount
from amount am;
如果愿意,您可以使用where
子句作为join
执行此操作:
select (am.amount / ra.multiplier * ra.value) as calculated_amount
from amount am join
rate ra
on ra.name = am.name and
year(rate_date) = year(am.amount_year)
where ra.date = (select max(r2.rate_date)
from rate r2
where year(r2.rate_date) = year(r.rate_date) and
r2.name = ra.name
);
对于性能,从速率(名称、速率、日期、乘数、值)
上的索引开始。对于这两个查询
为了获得更好的性能,您可能需要将“year”作为一个单独的列存储在表中。您的子查询是相同的,因此您可以在一个表中完成这项工作:
select am.amount /
(select ra.multiplier * ra.value
from rate ra
where ra.rate_date = (select max(rate_date)
from rate
where year(rate_date) = year(am.amount_year) and name = am.rate_name) and ra.name = am.rate_name
)
) as calculated_amount
from amount am;
或者可以用以下措辞:
select am.amount /
(select ra.multiplier * ra.value
from rate ra
where year(ra.rate_date) = year(am.amount_year) and name = am.rate_name
order by ra.rate_date desc
limit 1
) as calculated_amount
from amount am;
如果愿意,您可以使用where
子句作为join
执行此操作:
select (am.amount / ra.multiplier * ra.value) as calculated_amount
from amount am join
rate ra
on ra.name = am.name and
year(rate_date) = year(am.amount_year)
where ra.date = (select max(r2.rate_date)
from rate r2
where year(r2.rate_date) = year(r.rate_date) and
r2.name = ra.name
);
对于性能,从速率(名称、速率、日期、乘数、值)
上的索引开始。对于这两个查询
为了获得更好的性能,您可能需要将“year”作为一个单独的列存储在表中。您可以使用单个子查询来获取每年的最新乘数和值。然后将其与
amount
表合并进行除法
SELECT am.amount / (r2.multiplier * r2.value) AS calculated_amount
FROM amount AS am
JOIN (SELECT YEAR(rate_date) AS year, MAX(rate_date) AS maxdate
FROM rate
GROUP BY year) AS r1 ON YEAR(am.rate_date) = r1.year
JOIN rate AS r2 ON r1.maxdate = r2.rate_date
您可以使用单个子查询来获取每年的最新乘数和值。然后将其与
amount
表合并进行除法
SELECT am.amount / (r2.multiplier * r2.value) AS calculated_amount
FROM amount AS am
JOIN (SELECT YEAR(rate_date) AS year, MAX(rate_date) AS maxdate
FROM rate
GROUP BY year) AS r1 ON YEAR(am.rate_date) = r1.year
JOIN rate AS r2 ON r1.maxdate = r2.rate_date
您可以使用单个子查询来获取每年的最新乘数和值。然后将其与
amount
表合并进行除法
SELECT am.amount / (r2.multiplier * r2.value) AS calculated_amount
FROM amount AS am
JOIN (SELECT YEAR(rate_date) AS year, MAX(rate_date) AS maxdate
FROM rate
GROUP BY year) AS r1 ON YEAR(am.rate_date) = r1.year
JOIN rate AS r2 ON r1.maxdate = r2.rate_date
您可以使用单个子查询来获取每年的最新乘数和值。然后将其与
amount
表合并进行除法
SELECT am.amount / (r2.multiplier * r2.value) AS calculated_amount
FROM amount AS am
JOIN (SELECT YEAR(rate_date) AS year, MAX(rate_date) AS maxdate
FROM rate
GROUP BY year) AS r1 ON YEAR(am.rate_date) = r1.year
JOIN rate AS r2 ON r1.maxdate = r2.rate_date
“表之间没有物理连接”是什么意思?它们在不同的数据库服务器上?@Barmar没有外键,没有索引等。假设它们可能在不同的架构上。所以你的意思是没有逻辑连接。@Barmar你是对的。我编辑了我的帖子。你说的“表之间没有物理连接”是什么意思?它们在不同的数据库服务器上?@Barmar没有外键,没有索引等。假设它们可能在不同的架构上。所以你的意思是没有逻辑连接。@Barmar你是对的。我编辑了我的帖子。你说的“表之间没有物理连接”是什么意思?它们在不同的数据库服务器上?@Barmar没有外键,没有索引等。假设它们可能在不同的架构上。所以你的意思是没有逻辑连接。@Barmar你是对的。我编辑了我的帖子。你说的“表之间没有物理连接”是什么意思?它们在不同的数据库服务器上?@Barmar没有外键,没有索引等。假设它们可能在不同的架构上。所以你的意思是没有逻辑连接。@Barmar你是对的。我编辑了我的帖子。