我找到了许多其他类似查询的答案,但都不满足我的要求,因此就是问题。
首先,数据:
orderid type year change
1111 1 2018 333
1111 2 2018 4652
1111 1 2019 3645
1111 3 2019 444
2222 1 2018 6451
在订单号,类型和年份列上有一个联合键。因此,对于某种类型,每个订单每年可以有一个条目。
现在,所需的结果(选项1):
orderid type year change
1111 2 2018 4652
1111 1 2019 3645
我正在寻找的是每年给定订单的最大“更改”值。类型无关紧要。 “ 1111”是传递给查询的示例订单。
并且如果可以进一步改善第一个挑战,则理想情况下,我希望从上述答案中获得变更的总和。因此理想的结果应如下所示(选项2):
orderid change
1111 8297
我还没有尝试得到第二个答案,从技术上讲,这应该是对结果进行附加查询以汇总返回的更改列的简便包装。但是,到目前为止,我为第一个问题(并添加-没有成功)尝试过的是:
SELECT t1.*
FROM table1 t1
LEFT JOIN table1 t2
ON t1.orderid = t2.orderid AND t1.year = t2.year AND t1.change > t2.change
WHERE t2.change IS NULL
AND t1.orderid = '1111'
此查询返回的结果并非完全是期望的结果,其中一个最大值是正确的,而另一个不是:
orderid type year change
1111 1 2018 333
1111 1 2019 3645
是的。现在谁愿意保存我的星期五晚上?
总是很感谢帮助!
更新1: 我在上述所有内容中都包含sqlfiddle: SQLFiddle
答案 0 :(得分:1)
您的SQLFiddle无法正常工作有两个原因。首先,也是最重要的是,您将change
的值声明为VARCHAR
而不是INT
。结果,MySQL认为444
> 3645
。其次,JOIN
条件应该是t1.change < t2.change
,而不是t1.change > t2.change
。请参见updated SQLFiddle,它会提供您想要的结果:
orderid type year change
1111 2 2018 4652
1111 1 2019 3645
如果该字段必须保留VARCHAR
,则需要将JOIN
条件更改为
CAST(t1.change AS UNSIGNED) < CAST(t2.change AS UNSIGNED)
要获取更改的总和,只需将您的查询用作子查询,SUM
更改和GROUP BY orderid
:
SELECT orderid, SUM(`change`) AS total_change
FROM (SELECT t1.*
FROM table1 t1
LEFT JOIN table1 t2
ON t1.orderid = t2.orderid AND t1.year = t2.year AND t1.change < t2.change
WHERE t2.change IS NULL AND t1.orderid = '1111') t
GROUP BY orderid
输出:
orderid total_change
1111 8297
答案 1 :(得分:1)
尝试比较值时,您的问题是VARCHAR
类型。
因此,比较时您需要CAST
值,或者change your schema。
ALTER TABLE table1 MODIFY COLUMN `change` INT;
http://sqlfiddle.com/#!9/b2786a/6
SELECT t1.*
FROM table1 t1
LEFT JOIN table1 t2
ON t1.orderid = t2.orderid
AND t1.year = t2.year
AND CAST(t1.change AS UNSIGNED) < CAST(t2.change AS UNSIGNED)
WHERE t2.change IS NULL
AND t1.orderid = '1111';
SELECT t1.*
FROM table2 t1
LEFT JOIN table2 t2
ON t1.orderid = t2.orderid
AND t1.year = t2.year
AND t1.change < t2.change
WHERE t2.change IS NULL
AND t1.orderid = '1111'