减去 MySQL 表中的值

发布于 2024-12-07 22:07:53 字数 504 浏览 0 评论 0原文

我在两个不同的表中有价格,想要减去它们(当前价格-最后一天的价格)并以 DESC 形式对它们进行排序。我想知道是否可以使用单个 MySQL 命令来完成。

表结构

Table 1
id | Item Name | Date       | Price
 1 | alpha     | 2011-10-05 | 10
 2 | beta      | 2011-10-05 | 12
 3 | gamma     | 2011-10-05 | 14 

Table 2
id | Item Name | Date       | Price
 1 | alpha     | 2011-10-04 | 8
 2 | beta      | 2011-10-04 | 10
 3 | gamma     | 2011-10-04 | 12
 4 | alpha     | 2011-10-03 | 4
 5 | beta      | 2011-10-03 | 6
 6 | gamma     | 2011-10-03 | 8

I have prices in two different tables and want to subtract them (current price-last day price) and ORDER them in DESC form. I was wondering if it can be done using a single MySQL command.

Table Structure

Table 1
id | Item Name | Date       | Price
 1 | alpha     | 2011-10-05 | 10
 2 | beta      | 2011-10-05 | 12
 3 | gamma     | 2011-10-05 | 14 

Table 2
id | Item Name | Date       | Price
 1 | alpha     | 2011-10-04 | 8
 2 | beta      | 2011-10-04 | 10
 3 | gamma     | 2011-10-04 | 12
 4 | alpha     | 2011-10-03 | 4
 5 | beta      | 2011-10-03 | 6
 6 | gamma     | 2011-10-03 | 8

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

九公里浅绿 2024-12-14 22:07:53
SELECT 
table1.id, table1.`Item Name`,
table1.`Date` AS CurrDate, table1.Price AS CurrPrice,
table2.`Date` AS PrevDate, table2.Price AS PrevPrice,
table1.Price - table2.Price AS Difference
FROM table1
LEFT JOIN table2 ON table1.id = table2.id AND table1.`Date` - INTERVAL 1 DAY = table2.`Date`
ORDER BY Difference DESC

除了我使用 LEFT JOIN 的方式之外,这个查询没有什么特别的。我相信如果昨天的记录费率不可用,则最后三列将包含 NULL。输出:

id | Item Name | CurrDate   | CurrPrice | PrevDate   | PrevPrice | Difference
2  | beta      | 2011-10-05 | 12        | 2011-10-04 | 10        | 2
3  | gamma     | 2011-10-05 | 14        | 2011-10-04 | 12        | 2
1  | alpha     | 2011-10-05 | 10        | 2011-10-04 | 8         | 2
SELECT 
table1.id, table1.`Item Name`,
table1.`Date` AS CurrDate, table1.Price AS CurrPrice,
table2.`Date` AS PrevDate, table2.Price AS PrevPrice,
table1.Price - table2.Price AS Difference
FROM table1
LEFT JOIN table2 ON table1.id = table2.id AND table1.`Date` - INTERVAL 1 DAY = table2.`Date`
ORDER BY Difference DESC

There is nothing special about this query except the way I've used the LEFT JOIN. I believe if yesterday's rates for a record are not available, the the last three columns would contain NULL. Output:

id | Item Name | CurrDate   | CurrPrice | PrevDate   | PrevPrice | Difference
2  | beta      | 2011-10-05 | 12        | 2011-10-04 | 10        | 2
3  | gamma     | 2011-10-05 | 14        | 2011-10-04 | 12        | 2
1  | alpha     | 2011-10-05 | 10        | 2011-10-04 | 8         | 2
暮色兮凉城 2024-12-14 22:07:53
SELECT 
  a.price as price1
  , IFNULL(b.price,'(no data)') as price2
  , (a.price - IFNULL(b.price,0)) as difference
FROM table1 a
LEFT JOIN table2 b ON (a.`item name` = b.`item name`)
GROUP BY a.`item name`
HAVING IFNULL(b.`date`,'') = MAX(IFNULL(b.`date`,'')

这是它的工作原理。

它从 2 个表中选择数据:表 1 中的所有数据和表 2 中的匹配数据。
如果它无法从 table2 中找到匹配的数据,它将用 null 值代替丢失的行。 (left join)

然后根据 table1.item 名称将 (group by) 行分组在一起
这将每个项目合并多行。
having 子句通过仅从 table2 中选择最新的日期行来修复此问题。

selecthaving 子句中内置了一个小修正,以处理 table2 中没有数据与 table1 匹配的情况。

应该是:

SELECT 
  s.closing as price1
  , IFNULL(sh.closing,'(no data)') as price2
  , (s.closing - IFNULL(sh.closing,0)) as difference 
FROM stocks s 
LEFT JOIN stockhistory sh ON (s.symbol = sh.symbol) 
GROUP BY s.symbol 
HAVING IFNULL(sh.edate,'') = MAX(IFNULL(sh.edate,'')
LIMIT 30 OFFSET 0;
SELECT 
  a.price as price1
  , IFNULL(b.price,'(no data)') as price2
  , (a.price - IFNULL(b.price,0)) as difference
FROM table1 a
LEFT JOIN table2 b ON (a.`item name` = b.`item name`)
GROUP BY a.`item name`
HAVING IFNULL(b.`date`,'') = MAX(IFNULL(b.`date`,'')

Here's how it works.

It selects data from 2 tables: All data from table1 and matching data from table2.
If it cannot find matching data from table2 it will substitute null values in place of the missing rows. (left join)

Then it groups (group by) rows together based on table1.item name.
This combines multiple rows per item.
The having clause fixes this by only selecting the newest date rows from table2.

A small correction is build into the select and having clauses to deal with the case when there is no data in table2 to match table1.

Your query should be:

SELECT 
  s.closing as price1
  , IFNULL(sh.closing,'(no data)') as price2
  , (s.closing - IFNULL(sh.closing,0)) as difference 
FROM stocks s 
LEFT JOIN stockhistory sh ON (s.symbol = sh.symbol) 
GROUP BY s.symbol 
HAVING IFNULL(sh.edate,'') = MAX(IFNULL(sh.edate,'')
LIMIT 30 OFFSET 0;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文