SQLite:结合OR和and
这是我们继续提出的问题 假设一个表“下注表”SQLite:结合OR和and,sql,mysql,sqlite,Sql,Mysql,Sqlite,这是我们继续提出的问题 假设一个表“下注表” 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
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
SELECT wage
FROM wagetable
WHERE name LIKE '$Employee' OR name LIKE 'Default'
ORDER BY priority DESC, highhours DESC
LIMIT 1
如果第一个查询未能在lowhours和highhours之间找到$Hour,则第二个查询将启动:
SELECT wage
FROM wagetable
WHERE name LIKE '$Employee' OR name LIKE 'Default'
AND '$Hour' BETWEEN lowhours AND highhours
ORDER BY priority DESC
LIMIT 1
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:
这一点是为了让你可以定义一个工资表,如果有人得到的钱比其他人多,他们会得到一定数额的工资加上加班费。如果是标准工人,则将获得默认工资。如果$Employee
在列表中,则他将获得特殊工资
最低lowhours
将始终为0.0,lowhours
和highhours
对将永远不会有任何间隙(不允许40-50,然后跳过并执行60-70)。不确定的是最高的highhours
。因此,如果$Hour
高于$Employee
的最高highhours
,则应使用$Employee
的最高highhours
工资
比如,;如果“Betty Sue”工作200小时,它将获得Default
的最高highhours
工资。。。也就是200。因此,“贝蒂·苏”第200小时的工资是每小时200英镑
现在,如果布莱恩工作10000小时,他将不赚取默认
的最高高小时
工资……但他将赚取布莱恩的最高高小时
工资,即350
基准测试结果:
这是基于2000个查询(1000个用于匹配,1000个用于默认不匹配):
Timwi方法:4348毫秒
OMG Ponie方法:5843毫秒
我的方法使用了最多5个查询和至少2:5844毫秒以下是我在给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
由于在用户上选择匹配,因此/etc位于联合体的上部,如果存在这样的记录,它将是第一行。如果没有匹配项,则默认匹配项将是第一行。默认值总是在结果集中,因此需要限制
..我相信这是实现您想要的最直接的方法:
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)
)
它与您在另一个问题中描述的一样:
- 检索$Employee的工资李>
- 如果$Employee没有行,这将导致NULL,因此ISNULL生效李>
- 仅当第一个结果为NULL时,才会检索默认行
然而,我觉得我应该指出,您在这个问题中提出的问题与此有所不同。我的查询没有找到具有匹配的lowhours/highhours间隔的默认行,它只会返回默认值为最高highhours的行。我不知道问题中的查询是否真的是您想要的,但它似乎更有可能,因此这里有一个查询,与您在这个问题中实际提出的问题相当:
我不相信这个查询符合问题的要求。@Timwi:请看前面的问题-如果在单个查询中没有匹配项,OP希望获得默认值。好的,我发布了一个新答案,答案比你的答案短得多。除非我做错了什么;使用“Brian2”(未找到,因此应为默认值)返回100,而不是预期的200(200,因为其最高值和小时数为99999)选择s.wage FROM(从WAGETABLE x中选择x.wage,其中x.name(如“Brian2”)和“999999”,在x.lowhours和x.highhours之间,联合会从WAGETABLE y中选择y.wage FROM,其中y.name(如“默认值”)s限制1;@@@Debug(540)8/21/2010 11:10:26 PM$msg=Wage='100'@Brian:没有意义-您得到了默认值(到目前为止是正确的),但子查询不起作用?尝试分别运行联合的最后一半——默认部分。我可以把它改写成一个连接…+1:在解释中仍然会有3行,就像我的一样。但是subselect——使用orderby/etc的能力——使它更有能力。我想听听你和我的答案的性能比较;我觉得有些事情不对劲。SQLite在ISNULL上使用IFNULL…也许这就是问题所在。。。还有x.lowhours和x.highhours,x。不应该在那里。对不起;我想我应该先更好地测试我的例子……这是上一个问题的直接延续。我不想问这么多问题,只能奖励一个人。。。我将编辑我正在寻找的内容…因为你给我的内容效果更好,但仍然不好。根据我编辑中的示例,这是你当前的内容返回给我的内容…格式为预期答案,你的答案::100100 154154 200200 200200 275200 350200。。。。。。所以当它预计275的时候,这给了我200。。当它预期为350时,这给了我200。我看不出它如何能为输入返回200(Brian,51)
,以及您查询的数据