这是Selecting the highest salary
假设一张赌桌
name lowhours highhours wage priority
Default 0.0 40.0 100 0
Default 40.0 50.0 150 0
Default 50.0 70.5 154 0
Default 70.5 100.0 200 0
Brian 0.0 40.0 200 1
Brian 40.0 50.0 250 1
Brian 50.0 60.0 275 1
Brian 60.0 70.0 300 1
Brian 70.0 80.0 325 1
Brian 80.0 9999.0 350 1
Chad 0.0 40.0 130 1
Chad 40.0 9999.0 170 1
目前,我每秒执行3-4次两种类型的查询,因此性能是关键,不是真正的可读性(但首选)。
此查询仅当$Hour介于lowhours和highhours之间时选择工资:
SELECT wage
FROM wagetable
WHERE name LIKE '$Employee' OR name LIKE 'Default'
AND '$Hour' BETWEEN lowhours AND highhours
ORDER BY priority DESC
LIMIT 1
如果第一个查询未能在lowhours和highhours之间找到$Hour,则此第二个查询将启动:
SELECT wage
FROM wagetable
WHERE name LIKE '$Employee' OR name LIKE 'Default'
ORDER BY priority DESC, highhours DESC
LIMIT 1
我想看看是否可以有一个查询,在这个查询中,我可以将两者结合起来,在一个查询中执行相同的操作
编辑:
因为我没有正确地测试上面的查询。。我会用英语告诉你我想要什么和答案的例子。
它将检查表上存在的$$雇员,然后使用它。如果没有,则检查“Default”。一旦它知道了名字,它就会检查$Hour是否在已知的lowhours和highhours之间,如果它知道了,则选择该工资,如果它高于列出的任何值,则自动获取最高小时的工资。
以下是一些价值观。请注意,“山姆”不在桌子上,所以他将是“默认的”
示例遵循以下格式:
(姓名,时间)预期答案
(Sam, 1) 100
(Sam, 51) 154
(Sam, 999999) 200
(Brian, 1) 200
(Brian, 51) 275
(Brian, 999999) 350
这是另一张表,你可以快速参考,记住山姆是“默认的”
name lowhours highhours wage priority
Default 0.0 40.0 100 0
Default 40.0 50.0 150 0
Default 50.0 70.5 154 0
Default 70.5 100.0 200 0
Brian 0.0 40.0 200 1
Brian 40.0 50.0 250 1
Brian 50.0 60.0 275 1
Brian 60.0 70.0 300 1
Brian 70.0 80.0 325 1
Brian 80.0 9999.0 350 1
编辑2:
这一点是,你可以定义一个工资表,如果有人得到的钱比其他人多,他们会得到一定数额的工资加上加班费。如果是标准工人,那么将获得
Default
工资。如果$Employee
在名单上,他就会得到特别的工资。最低的
lowhours
将始终为0.0,lowhours
和highhours
对将永远不会有任何间隙(它不允许40-50,然后跳过并执行60-70)。不确定的是最高的highhours
。因此,如果$Hour
高于$Employee
的最高highhours
,则应使用$Employee
的最高highhours
工资。例如,如果“贝蒂苏”工作200小时,它将得到最高的工资。。。是200。因此,“贝蒂·苏”在第200小时的工资是每小时200英镑。
现在,如果布赖恩工作10000小时,他将不会获得最高的工资,但相反,他将获得最高的工资,即350。
基准的结果:
这基于2000个查询(1000个用于匹配,1000个用于默认不匹配):
Timwi方法:4348毫秒
OMG-Ponie方法:5843毫秒
我的方法最多使用5个查询,最少使用2:5844毫秒
最佳答案
以下是我在给亚历克斯的评论中提到的:
SELECT s.wage
FROM (SELECT x.wage
FROM WAGETABLE x
WHERE x.name LIKE '$Employee'
AND '$Hour' BETWEEN x.lowhours AND x.highhours
UNION ALL
SELECT y.wage AS wage
FROM WAGETABLE y
JOIN (SELECT wt.name,
MAX(wt.highhours) AS max_hours
FROM WAGETABLE wt
GROUP BY wt.name) bb ON bb.name = y.name
AND bb.max_hours = y.highhours
WHERE y.name LIKE '$Employee'
UNION ALL
SELECT t.wage
FROM WAGETABLE t
WHERE t.name = 'Default'
AND '$Hour' BETWEEN t.lowhours AND t.highhours
UNION ALL
SELECT z.wage
FROM WAGETABLE z
JOIN (SELECT wt.name,
MAX(wt.highhours) AS max_hours
FROM WAGETABLE wt
GROUP BY wt.name) aa ON aa.name = z.name
AND aa.max_hours = z.highhours
WHERE z.name LIKE 'Default') s
LIMIT 1
以前:
SELECT s.wage
FROM (SELECT x.wage
FROM WAGETABLE x
WHERE x.name LIKE '$Employee'
AND '$Hour' BETWEEN x.lowhours AND x.highhours
UNION ALL
SELECT y.wage
FROM WAGETABLE y
WHERE y.name LIKE 'Default'
AND y.highhours = (SELECT MAX(highhours)
FROM WAGETABLE wt
WHERE wt.name = y.name)) s
LIMIT 1
因为在用户/ ETC上选择匹配是在联盟的上部,如果存在这样的记录,它将是第一行。如果没有匹配项,则默认匹配项将是第一行。默认值将始终在结果集中,因此需要
LIMIT
。。。