这是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
如果第一个查询在下班时间和下午之间找不到$ Hour,则第二个查询起飞:
SELECT wage
FROM wagetable
WHERE name LIKE '$Employee' OR name LIKE 'Default'
ORDER BY priority DESC, highhours DESC
LIMIT 1
我希望看看是否有一个查询,我可以将两者结合起来只在一个查询中做同样的事情
编辑:
因为我没有正确测试上述查询..我会用英语告诉你我想要的东西和答案的例子。
它会检查表上是否存在$ Employee,然后使用它。如果没有,那么请检查“默认”。一旦知道了名字,它就会检查$ Hour是否在已知的工作时间和工作时间之间,如果确实如此,那么选择该工资,如果它高于列出的任何工资,则自动获取最高工时的工资。
以下是一些值。请注意,“sam”不在桌面上,所以他将是'默认' 示例遵循以下格式: (姓名,小时)预期答案
(Sam, 1) 100
(Sam, 51) 154
(Sam, 999999) 200
(Brian, 1) 200
(Brian, 51) 275
(Brian, 999999) 350
这是表格,所以你可以快速参考,记住Sam将是'默认'
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
将-allways-为0.0,lowhours
和highhours
对将不会有任何差距(它将不允许40-50然后跳过做60-70)。不确定的是最高highhours
。因此,$Hour
高于$Employee
的最高highhours
,那么它应该使用$Employee
的最高highhours
工资。
例如;如果“Betty Sue”工作200小时,它将获得Default
最高highhours
工资......即200.因此,“Betty Sue”在第200小时的工资是每小时200。
如果布莱恩工作10000小时,他将不获得Default
最高highhours
工资...但相反,他将获得Brian
的工资最高highhours
工资,即350。
基准测试的结果:
这是基于2000个查询(匹配为1000,默认不匹配为1000):
Timwi的方法:4348毫秒
OMG Ponie的方法:5843毫秒
我的方法最多使用5个查询,至少2:5844毫秒
答案 0 :(得分:3)
我相信这是做你想做的最直接的方式:
SELECT IFNULL(
(SELECT wage FROM WAGETABLE WHERE name LIKE '$Employee'
AND '$Hour' BETWEEN lowhours AND highhours),
(SELECT wage FROM WAGETABLE WHERE name LIKE 'Default'
ORDER BY highhours DESC LIMIT 1)
)
它完成了你在另一个问题中描述的内容:
但是,我觉得我应该指出您在此问题中发布的查询不同的。我的查询找不到具有匹配 lowhours / highhours 间隔的默认行,它只返回具有最高的那一行highhours 表示默认值。我不知道问题中的查询是否真的是你想要的,但似乎更有可能,因此这里的查询等同于你在这个问题中实际提出的问题:< / p>
SELECT IFNULL(
(SELECT wage FROM WAGETABLE WHERE (name LIKE '$Employee' OR name='Default')
AND '$Hour' BETWEEN lowhours AND highhours
ORDER BY priority DESC LIMIT 1),
(SELECT wage FROM WAGETABLE WHERE name LIKE '$Employee' OR name='Default'
ORDER BY priority DESC, highhours DESC LIMIT 1)
)
答案 1 :(得分:1)
以下是我在对Alex的评论中提到的内容:
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
由于在UNION的上半部分选择了用户匹配,如果存在这样的记录 - 它将是第一行。如果没有匹配项,则默认匹配将是第一行。默认值始终位于结果集中,因此需要LIMIT
...