我正在尝试构建一个执行以下操作的查询;
1)查询具有给定'acctuniqueid'的行,该行具有'acctoutputoctets'的第二大值,或者如果找不到匹配的行,则返回0
2)执行以下计算250 + 350-('acctinputoctets'的返回值+'acctoutputoctets'的返回值'||“0”)
使用“a25d16693309cdb4807effe00a9f076c”作为“acctuniqueid”字段。
表名:radacct
+-----------+----------------------------------+-----------------+------------------+
| radacctid | acctuniqueid | acctinputoctets | acctoutputoctets |
+-----------+----------------------------------+-----------------+------------------+
| 5 | a25d16693309cdb4807effe00a9f076c | 150 | 250 |
| 8 | a25d16693309cdb4807effe00a9f076c | 250 | 350 |
+-----------+----------------------------------+-----------------+------------------+
+-----------+----------------------------------+-----------------+------------------+
| radacctid | acctuniqueid | acctinputoctets | acctoutputoctets |
+-----------+----------------------------------+-----------------+------------------+
| 4 | a25d16693309cdb4807effe00a9f076c | 250 | 350 |
+-----------+----------------------------------+-----------------+------------------+
在示例#1中:250 + 350-(150 + 250)= 200 所以预期的结果是200
在示例#2中:250 + 350-(0)= 600 所以预期的结果是600
查询我到目前为止一直在修补:
SELECT (SUM(250)+SUM(350)-((SUM(IFNULL(acctinputoctets,0)))+
(SUM(IFNULL(acctoutputoctets,0))))
)
FROM
( SELECT *,IFNULL(acctinputoctets,0),
IFNULL(acctoutputoctets,0)
FROM radacct
WHERE acctuniqueid = 'a25d16693309cdb4807effe00a9f076c'
ORDER BY acctoutputoctets DESC
LIMIT 1 , 1
) as meh
返回示例#1的内容,但是对于示例#2,我得到NULL作为结果。
应该注意的是,在上面的查询“250”中,手动添加了“350”和“a25d16693309cdb4807effe00a9f076c”以用于测试和可读性目的,但稍后将替换为运行时变量输出。
我尝试过IFNULL和COALESCE的各种迭代,组合和放置,并尝试在线搜索类似的问题/解决方案帖子 - 但是我找不到任何与我正在做的事情相近的事情有“啊哈!”那一刻。
考虑到我(缺乏)SQL经验,我猜测(a)这是非常简单的事情,有人会立即发现,和/或(b)我已经完全错误地查询了我的查询是一种不同的,更正确的结构化查询方式,这超出了我目前的知识水平。
今天早上凌晨4点,经过几个小时的咒骂,恳求和讨价还价 - 我终于承认了失败,所以提供的任何援助都会受到高度赞赏。
提前致谢。
答案 0 :(得分:0)
这似乎对我有用:
示例#1
CREATE TABLE radacct (
radacctid int,
acctuniqueid nvarchar(50),
acctinputoctets int,
acctoutputoctets int
);
INSERT INTO radacct values
(5, 'a25d16693309cdb4807effe00a9f076c', 150, 250),
(8, 'a25d16693309cdb4807effe00a9f076c', 250, 350)
SELECT 250 + 350
- COALESCE((SELECT acctinputoctets FROM radacct ORDER BY acctoutputoctets DESC LIMIT 1, 1), 0)
- COALESCE((SELECT acctoutputoctets FROM radacct ORDER BY acctoutputoctets DESC LIMIT 1, 1), 0)
示例#2
CREATE TABLE radacct (
radacctid int,
acctuniqueid nvarchar(50),
acctinputoctets int,
acctoutputoctets int
);
INSERT INTO radacct values
(4, 'a25d16693309cdb4807effe00a9f076c', 250, 350);
SELECT 250 + 350
- COALESCE((SELECT acctinputoctets FROM radacct ORDER BY acctoutputoctets LIMIT 1, 1), 0)
- COALESCE((SELECT acctoutputoctets FROM radacct ORDER BY acctoutputoctets LIMIT 1, 1), 0)
但是,如果在acctoutputoctects中有多个行绑定第二个值,那么结果将是非常随机的。例如,如果在示例#1中,两行都有350作为acctoutputoctects列中的值,则结果将取决于值的插入方式,因为两行都符合条件,但在acctinputoctects列中具有不同的值(这会影响答案)。如果您提供一些关于如何打破关系的更多信息,我很乐意修改代码以适应它。
答案 1 :(得分:0)
这里的一个主要问题是决定在抽签的情况下进行选择。这个讨厌的代码试图在离开加入之前根据radacctid选择最近的最高和第二高值以获得最终结果
drop table if exists t;
create table t( radacctid int, acctuniqueid varchar(40), acctinputoctets int, acctoutputoctets int);
insert into t values
( 5 , 'a25d16693309cdb4807effe00a9f076c' , 150 , 250),
( 8 , 'a25d16693309cdb4807effe00a9f076c' , 250 , 350),
( 9 , 'a25d16693309cdb4807effe00a9f076c' , 200 , 250),
( 4 , 'b25d16693309cdb4807effe00a9f076c' , 10 , 10),
( 6 , 'b25d16693309cdb4807effe00a9f076c' , 250 , 350),
( 7 , 'c25d16693309cdb4807effe00a9f076c' , 20 , 30);
select mm.acctuniqueid,mm.maxid,mm.maxin,mm.maxout ,
sm.acctuniqueid,sm.secondmaxid,sm.secondmaxin,sm.secondmaxout,
(ifnull(mm.maxin,0) + ifnull(mm.maxout,0)) -
(ifnull(sm.secondmaxin,0) + ifnull(sm.secondmaxout,0)) as Total
from
(
select t.acctuniqueid,t.radacctid maxid,t.acctinputoctets maxin,t.acctoutputoctets maxout
from t
join
(
select t.acctuniqueid,s.maxout, max(radacctid) maxid #adjust maxid as required
from
(
select acctuniqueid, max(acctoutputoctets) maxout
from t
where acctoutputoctets = (select max(acctoutputoctets) from t t1 where t1.acctuniqueid = t.acctuniqueid)
group by acctuniqueid
) s
join t on t.acctuniqueid = s.acctuniqueid and t.acctoutputoctets = s.maxout
group by t.acctuniqueid,s.maxout
) s
on s.acctuniqueid = t.acctuniqueid and s.maxid = t.radacctid
) mm
left join
(
select t.acctuniqueid,t.radacctid secondmaxid,t.acctinputoctets secondmaxin,t.acctoutputoctets secondmaxout
from t
join
(
select t.acctuniqueid,s.secondmaxout, max(radacctid) secondmaxid #adjust secondmaxid as required
from
(
select acctuniqueid, max(acctoutputoctets) secondmaxout
from t
where acctoutputoctets < (select max(acctoutputoctets) from t t1 where t1.acctuniqueid = t.acctuniqueid)
group by acctuniqueid
) s
join t on t.acctuniqueid = s.acctuniqueid and t.acctoutputoctets = secondmaxout
group by t.acctuniqueid,s.secondmaxout
) s
on s.acctuniqueid = t.acctuniqueid and s.secondmaxid = t.radacctid
) sm
on mm.acctuniqueid = sm.acctuniqueid
+----------------------------------+-------+-------+--------+----------------------------------+-------------+-------------+--------------+-------+
| acctuniqueid | maxid | maxin | maxout | acctuniqueid | secondmaxid | secondmaxin | secondmaxout | Total |
+----------------------------------+-------+-------+--------+----------------------------------+-------------+-------------+--------------+-------+
| a25d16693309cdb4807effe00a9f076c | 8 | 250 | 350 | a25d16693309cdb4807effe00a9f076c | 9 | 200 | 250 | 150 |
| b25d16693309cdb4807effe00a9f076c | 6 | 250 | 350 | b25d16693309cdb4807effe00a9f076c | 4 | 10 | 10 | 580 |
| c25d16693309cdb4807effe00a9f076c | 7 | 20 | 30 | NULL | NULL | NULL | NULL | 50 |
+----------------------------------+-------+-------+--------+----------------------------------+-------------+-------------+--------------+-------+
3 rows in set (0.01 sec)
如果您只是需要最大值(或最小值)以便在抽奖时使用最大值,那么可能会简化。