我有一张像这样的表MyTable
:
Date Qty Price
2017-07-01 2 5.00
2017-07-08 3 4.00
2017-08-08 1 6.00
如果我进行查询以获得最大总费用:
SELECT max(Qty * Price) FROM MyTable
我得到12.00
这是正确的。
我如何拥有2017-07-08的相应日期? 如果有几个相等的最大值,我希望有最小(最早)的日期。
答案 0 :(得分:1)
create table MyTable (date datetime, qty int, price int)
go
insert into MyTable(date,qty,price)
values
('2017-07-01', 2, 5.00),
('2017-07-08', 3, 4.00),
('2017-08-08', 1, 6.00);
with q as
(
select *, row_number() over (order by qty*price desc) rn
from MyTable
)
select date, qty, price
from q
where rn = 1;
输出
date qty price
----------------------- ----------- -----------
2017-07-08 00:00:00.000 3 4
(1 row(s) affected)
答案 1 :(得分:1)
如果您只需要一行具有最大数量*价格,最早的一天
SELECT TOP(1) *
FROM MyTable
ORDER BY Qty * Price DESC, [Date];
如果您需要具有相同最大数量*价格值的所有行
SELECT TOP(1) WITH TIES *
FROM MyTable
ORDER BY Qty * Price DESC;
答案 2 :(得分:1)
只为了它的乐趣...
SELECT
[Date] = CAST(SUBSTRING(mv.MaxBin, 9, 8) AS DATE),
Qty = CAST(SUBSTRING(mv.MaxBin, 17, 4) AS INT),
Price = CAST(SUBSTRING(mv.MaxBin, 21, 8) AS MONEY)
FROM (
SELECT
MaxBin = MAX(CAST(td.Qty * td.Price AS BINARY(8)) + CAST(td.Date AS BINARY(8)) + CAST(td.Qty AS BINARY(4)) + CAST(td.Price AS BINARY(8)))
FROM
#TestData td
) mv;
编辑:这是如何以及为何有效......
正如您在开篇中所说,“SELECT max(Qty * Price)FROM MyTable”可以获得正确的值,但这无助于您从该行获取剩余的列。
所以我们的想法是进行计算,然后将其他列值连接到计算结果,这样我们就可以使用之前的逻辑[MAX(Qty * Price)获得所有需要的列。
将事物转换为固定长度的二进制值允许我们这样做。我们知道Qty * Price = ToalPrice或者数据类型INT * MONEY = MONEY,这是一个8字节的数据类型...所以我知道我可以将任何$ amount作为BINARY(8)投出并知道1)我以后总是可以将它转换回金钱,2)二进制值只有8个字符长3)我可以按照原始值对二进制进行排序。
同样适用于日期,这是一个3字节长的日期数据类型(是的,我使用了8而不是3 ...我已经习惯了DATETIME类型......我的那个很糟糕...)依此类推其他专栏。
因此,通过将二进制值连接在一起,我可以表示这些值的MAX,就像你使用max(Qty * Price)一样,但现在我拥有整行数据。现在,如果使用SUBSTRING函数将连接的二进制值分解回其组成部分(这很容易,因为我们确切知道每个部分的长度),并将它们转换回原始数据类型,就必须完成所有这些工作。