我有一个包含表xxx_facileforms_forms,xxx_facileforms_records和xxx_facileforms_subrecords的数据库。
xxx_facileforms_subrecords的列标题:
id | record | element | title | neame | type | value
使用element =' 101'过滤记录。 ..query返回正确的记录,但是当我将子查询添加到filete aditional element =' 4871'来自同一张表 - 返回了0条记录。
SELECT
F.id AS form_id,
R.id AS record_id,
PV.value AS prim_val,
COUNT(PV.value) AS count
FROM
xxx_facileforms_forms AS F
INNER JOIN xxx_facileforms_records AS R ON F.id = R.form
INNER JOIN xxx_facileforms_subrecords AS PV ON R.id = PV.record AND PV.element = '101'
WHERE R.id IN (SELECT record FROM xxx_facileforms_records WHERE record = R.id AND element = '4871')
GROUP BY PV.value
这看起来不错吗?
谢谢!
修改
感谢您的支持和想法!是的,我留下了许多猜测。抱歉。某些输入/输出表数据可能有助于使其更清晰。
_facileforms_form:
id | formname
---+---------
1 | myform
_facileforms_records:
id | form | submitted
----+------+--------------------
163 | 1 | 2014-06-12 14:18:00
164 | 1 | 2014-06-12 14:19:00
165 | 1 | 2014-06-12 14:20:00
_facileforms_subrecords:
id | record | element | title | name|type | value
-----+--------+---------+--------+-------------+--------
5821 | 163 | 101 | ticket | radio group | flight
5822 | 163 | 4871 | status | select list | canceled
5823 | 164 | 101 | ticket | radio group | flight
5824 | 165 | 101 | ticket | radio group | flight
5825 | 165 | 4871 | status | select list | canceled
成功的查询结果:
form_id | record_id | prim_val | count
1 | 163 | flight | 2
所以我必须从那些存在_subrecord元素 - 4871的记录(在这种情况下为163和165)返回值数据(并对这些记录求和)。
再次谢谢你!
答案 0 :(得分:0)
不,看起来不太对劲。有一个谓词“ R.id IN (subquery)
”,但该子查询本身引用了 R.id
;它是一个相关的子查询。看起来有些东西加倍了。 (我们假设 id
是每个表中的唯一或主要键。)
子查询引用标识符element
...我们看到该标识符的唯一其他引用来自_subrecords
表(我们在_records
中看不到对该列的任何引用} table ...如果element
中没有_records
列,那么这是对element
中PV
列的引用,并且子查询中的谓词永远不会为true同时PV.element='101'
谓词为真。
使用表别名限定列引用的荣誉,这使得查询(和EXPLAIN输出)更容易阅读;读者不需要在表定义中进行挖掘,以确定哪个表包含哪些表,哪些表包含哪些列。但请将该模式用于下一步,并在查询中限定所有列引用,包括子查询中的列引用。
由于对element
的引用不合格,我们只能猜测_records
表是否包含名为element
的列。
如果目标是仅使用R
从element='4871'
返回行,我们就可以...
WHERE R.element='4871'
但是,鉴于你已经厌倦了使用子查询,我怀疑这不是你想要的。
您可能尝试从R
返回_form
的所有行,但仅针对_form
,其中至少有一个关联的_record
element='4871'
即可。我们可以使用 IN (subquery)
或 EXISTS (correlated_ subquery)
谓词或 anti-join
模式。我将举例说明这些查询模式;我可以对规范做一些猜测,但我只会猜测你真正希望返回的内容。
但我猜这不是你想要的。我怀疑_records
实际上并不包含名为element
的列。
该查询已经限制从PV
返回的行与element='101'
的行。)
这是一些示例数据和示例输出有助于解释实际规范的情况;这将是开发所需SQL的基础。
<强>后续强>
我只是猜测......也许你想要的东西很简单。也许你想要返回元素值为'101'或'4913'的行。
IN
比较运算符可以方便地表达OR条件,即列等于列表中的值:
SELECT F.id AS form_id
, R.id AS record_id
, PV.value AS prim_val
, COUNT(PV.value) AS count
FROM xxx_facileforms_forms F
JOIN xxx_facileforms_records R
ON R.form = F.id
JOIN xxx_facileforms_subrecords PV
ON PV.record = R.id
AND PV.element IN ('101','4193')
GROUP BY PV.value
注意:此查询(如OP查询)使用GROUP BY的非标准MySQL扩展,它允许在SELECT列表中返回非聚合表达式(例如裸列)。
非聚合表达式(在本例中为F.id
和R.id
)返回的值将是“组”中包含的行中的值。但是因为这些行可能有多行和不同的值,所以返回哪个值不确定。 (其他数据库会拒绝此语句,除非我们将这些列包装在聚合函数中,例如MIN()或MAX()。)
<强>后续强>
我注意到你在答案中添加了有关问题的信息......这些信息最好添加作为编辑问题,因为它不是答案问题。我冒昧地复制那个,并重新格式化。
这个例子让你更加清楚你想要完成什么。
我认为最容易理解是使用EXISTS谓词,检查符合某些条件的行是否“存在”,并排除不存在这样的行的行。这将使用_subrecords表的相关子查询,检查是否存在匹配的行:
SELECT f.id AS form_id
, r.id AS record_id
, pv.value AS prim_val
, COUNT(pv.value) AS count
FROM xxx_facileforms_forms f
JOIN xxx_facileforms_records r
ON r.form = f.id
JOIN xxx_facileforms_subrecords pv
ON pv.record = r.id
AND pv.element = '101'
-- only include rows where there's also a related 4193 subrecord
WHERE EXISTS ( SELECT 1
FROM xxx_facileforms_subrecords sx
WHERE sx.element = '4193'
AND sx.record = r.id
)
--
GROUP BY pv.value
(我认为OP就是需要子查询的想法。)
鉴于查询中存在GROUP BY,我们实际上可以使用常规连接操作完成等效结果,以及对_subrecords表的第二次引用。
连接操作通常比使用EXISTS谓词更有效。
(请注意,现有的GROUP BY
子句将消除JOIN操作可能引入的任何“重复”,因此这将返回相同的结果。)
SELECT f.id AS form_id
, r.id AS record_id
, pv.value AS prim_val
, COUNT(pv.value) AS count
FROM xxx_facileforms_forms f
JOIN xxx_facileforms_records r
ON r.form = f.id
JOIN xxx_facileforms_subrecords pv
ON pv.record = r.id
AND pv.element = '101'
-- only include rows where there's also a related 4193 subrecord
JOIN xxx_facileforms_subrecords sx
ON sx.record = r.id
AND sx.element = '4193'
--
GROUP BY pv.value
答案 1 :(得分:0)
感谢您的支持和想法!是的,我留下了很多猜测..抱歉。因此,某些输入/输出表数据可能会有所帮助。
<强> _facileforms_form:强>
标题 - &gt; id |表格名称
1 | myForm会
<强> _facileforms_records:强>
标题 - &gt; id |形式|提交
163 | 1 | 2014-06-12 14:18:00
164 | 1 | 2014-06-12 14:19:00
165 | 1 | 2014-06-12 14:20:00
<强> _facileforms_subrecords 强>
标题 - &gt; id |记录|元素|标题|名字|类型|值
5821 | 163 | 101 |票|广播组|飞行
5822 | 163 | 4871 |状态|选择列表|取消
5823 | 164 | 101 |票|广播组|飞行
5824 | 165 | 101 |票|广播组|飞行
5825 | 165 | 4871 |状态|选择列表|取消
成功查询结果:
标题 - &gt; form_id | record_id | prim_val |计数
1 | 163 |航班| 2 强>
所以我必须从那些存在_subrecord元素 - 4871的记录(在这种情况下为163和165)返回值数据(并对这些记录求和)。
再次谢谢你!