问题 请考虑下表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mf="http://example.com/mf"
exclude-result-prefixes="xs mf"
version="2.0">
<xsl:param name="start-id">15492293</xsl:param>
<xsl:output method="text"/>
<xsl:key name="parent" match="related-documents/*" use="relation/child-doc/document-id/doc-number"/>
<xsl:function name="mf:get-ancestor-ids" as="xs:integer*">
<xsl:param name="item" as="element()"/>
<xsl:variable name="parent-id"
select="$item/relation/parent-doc/document-id/doc-number"/>
<xsl:variable name="parent"
select="key('parent', $parent-id, root($item))"/>
<xsl:sequence
select="xs:integer($parent-id), $parent/mf:get-ancestor-ids(.)"/>
</xsl:function>
<xsl:template match="/">
<xsl:value-of select="$start-id, mf:get-ancestor-ids(key('parent', $start-id))" separator=" -> "/>
</xsl:template>
</xsl:stylesheet>
对于每个+--------------+--------+--------+
| transactionID | Sgroup | Rgroup |
+--------------+--------+--------+
| 1 | A | I |
| 1 | A | J |
| 2 | B | B |
| 2 | B | K |
+--------------+--------+--------+
(2行与ID 1关联,两行ID为ID 2)我想选择transactionID
的行,如果Sgroup = Rgroup
中的任何行满足条件。否则,我想随机选择一行。对于每个transactionID
,最多一行满足transactionID
。我怎么能这样做?
尝试解决方案
我知道如何选择满足条件Sgroup = Rgroup
的行,如下所示:
Sgroup = Rgroup
我也知道如果不满足条件,如何随机选择一行(感谢this question):
SELECT *
FROM Transaction
WHERE Sgroup = Rgroup;
+---------------+--------+--------+
| transactionID | Sgroup | Rgroup |
+---------------+--------+--------+
| 2 | B | B |
+---------------+--------+--------+
如何将这两个表达式合并为一个?我尝试使用CASE表达式我没有达到目标。有人可以建议一个解决方案吗?
示例代码以下是生成表格的代码:
SELECT * FROM
(SELECT *
FROM Transaction
WHERE NOT transactionID IN
(SELECT transactionID
FROM Transaction
WHERE Sgroup = Rgroup)
ORDER BY RAND()) AS temp
GROUP BY temp.transactionID;
+---------------+--------+--------+
| transactionID | Sgroup | Rgroup |
+---------------+--------+--------+
| 1 | A | I |
+---------------+--------+--------+
答案 0 :(得分:3)
我认为变量可能是最简单的解决方案,如果你的意思是&#34;随机&#34;:
select t.*
from (select t.*,
(@rn := if(@i = transactionID, @rn + 1,
if(@i := transactionID, 1, 1)
)
) as rn
from (select t.*
from t
order by transactionID, (sgroup = rgroup) desc, rand()
) t cross join
(select @i := -1, @rn := 0) params
) t
where rn = 1;
如果是&#34;随机&#34;你的意思是&#34;任意&#34;,你可以使用这个快速而肮脏的技巧:
(select t.*
from t
where sgroup = rgroup
)
union all
(select t.*
from t
where not exists (select 1 from t t2 where t2.id = t.id and t2.sgroup = t2.rgroup)
group by transactionID
);
这会使用可怕的select *
与group by
,这是我强烈反对在几乎所有情况下使用的东西。但是,在这种情况下,您专门尝试将每个组缩减为 indeterminate 行,因此它看起来并不那么糟糕。我会注意到MySQL并不保证结果集中的列都来自同一行,尽管实际上它们也是如此。
最后,如果每行都有唯一的主键,则可以使用最简单的解决方案:
select t.*
from t
where t.id = (select t2.id
from t t2
where t2.transactionID = t.transactionID
order by (rgroup = sgroup) desc, rand()
);