我的目标是,为每个PID
选择2条test_sname
值为' 想要'和' 想要2 '发生在同一entry_date
上。我为包含entry_dates
的前5个test_snames
执行此操作。
这是我完成此任务的查询:
queryBuilder =
"""select PID, test_sname, test_value, units, ref_range, entry_date from labs
where PID=%s and (test_sname='want' or test_sname='want2') and entry_date in
(select entry_date from labs where PID=%s and test_sname in ('want', 'want2')
group by entry_date having count(*) = 2)
order by entry_date limit 10;""" % (pid, pid)
当entry_date只有两行包含test_sname
' 想要'或' want2 '。
PID |test_sname |test_value |units |entry_date
10000000 | want | 343 | U/L | 2008-01-01 01:01:01
10000000 | want2 | 984.34 | | 2008-01-01 01:01:01
10000000 | NA1 | 56 | % | 2008-01-01 01:01:01
10000000 | NA2 | 420 | mg/dL | 2008-01-01 01:01:01
10000000 | NA2 | 420 | mg/dL | 2008-01-02 01:01:01
10000000 | want | 343 | U/L | 2008-01-02 01:01:01
10000000 | want2 | 984.34 | | 2008-01-02 01:01:01
10000000 | NA1 | 26 | % | 2008-01-02 01:01:01
10000000 | NA2 | 410 | mg/dL | 2008-01-02 01:01:01
10000000 | NA2 | 455 | mg/dL | 2008-01-02 01:01:01
查询结果(正确):
PID |test_sname |test_value |units |entry_date
10000000 | want | 343 | U/L | 2008-01-01 01:01:01
10000000 | want2 | 984.34 | | 2008-01-01 01:01:01
10000000 | want | 343 | U/L | 2008-01-02 01:01:01
10000000 | want2 | 984.34 | | 2008-01-02 01:01:01
问题来自,例如,test_sname
想要'在同一个entry_date上,因为having count(*) = 2
不再有效。这样的数据没有结果。
PID |test_sname |test_value |units |entry_date
11111111 | want | 343 | U/L | 2009-10-26 07:25:00
11111111 | want2 | 984.34 | | 2009-10-26 07:25:00
11111111 | want | 189 | U/L | 2009-10-26 07:25:00
11111111 | NA1 | 50 | % | 2009-10-26 07:25:00
11111111 | NA2 | 40 | mg/dL | 2009-10-26 07:25:00
11111111 | NA3 | 84.55 | | 2009-10-26 07:25:00
11111111 | NA4 | 4.5 | thou/uL | 2009-10-26 07:25:00
11111111 | NA5 | 14.6 | g/dL | 2009-10-26 07:25:00
11111111 | NA6 | 0.96 | mg/dL | 2009-10-26 07:25:00
11111111 | want | 343 | U/L | 2009-10-30 07:25:00
11111111 | want2 | 984.34 | | 2009-10-30 07:25:00
11111111 | want | 189 | U/L | 2009-10-30 07:25:00
11111111 | NA1 | 6 | % | 2009-10-30 07:25:00
11111111 | NA2 | 40 | mg/dL | 2009-10-30 07:25:00
11111111 | NA3 | 84.55 | | 2009-10-30 07:25:00
11111111 | NA4 | 4.5 | thou/uL | 2009-10-30 07:25:00
11111111 | NA5 | 14.6 | g/dL | 2009-10-30 07:25:00
11111111 | NA6 | 0.96 | mg/dL | 2009-10-30 07:25:00
作为限制,我尝试在子查询中放置一个limit 2
(我知道这本身就不能解决问题),但它给出了这个错误,我认为我有最新的SQL版本,显然我不能在子查询中使用limit
。
This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
我意识到有多种方法可以解决这个问题 - 我可以选择所有值,然后以编程方式获取我需要的Python,但我正在寻找使用Python mySQL-connector编写的mySQL查询解决方案。我不会抱怨python解决方案。
我正在使用python v3.4.4和mySQL-connector v2.1.3以及MySQL服务器v5.7.11
谢谢你的时间!
答案 0 :(得分:1)
考虑通过子查询使用分组的运行计数。然后,在RowNo为1或2的任何位置进行过滤。这样,您将不需要传递参数,因为将处理所有PID。以下假设labs表具有唯一标识符ID
:
SELECT *
FROM
(SELECT PID, test_sname, test_value, units, ref_range, entry_date,
(SELECT count(*) FROM labs sub
WHERE sub.test_sname in ('want', 'want2')
AND sub.PID = labs.PID
AND sub.entry_date = labs.entry_date
AND sub.ID <= labs.ID) As RowNo
FROM labs
WHERE test_sname in ('want', 'want2')
) As dT
WHERE dT.RowNo <= 2
# PID test_sname test_value units ref_range entry_date RowNo
# 10000000 want 33 U/L 4-40 2008-01-01 01:01:01 1
# 10000000 want2 98.34 2008-01-01 01:01:01 2
# 10000000 want 33 U/L 4-40 2008-01-02 01:01:01 1
# 10000000 want2 98.34 2008-01-02 01:01:01 2
# 11111111 want 33 U/L Apr-40 2009-10-26 07:25:00 1
# 11111111 want2 98.34 2009-10-26 07:25:00 2
# 11111111 want 33 U/L Apr-40 2009-10-30 07:25:00 1
# 11111111 want2 98.34 2009-10-30 07:25:00 2