[英]How can I select a row within a group based on a condition in SQL?
問題請考慮下表:
+--------------+--------+--------+
| transactionID | Sgroup | Rgroup |
+--------------+--------+--------+
| 1 | A | I |
| 1 | A | J |
| 2 | B | B |
| 2 | B | K |
+--------------+--------+--------+
對於每個transactionID
(2行與ID 1相關聯,兩行ID為ID 2)我想選擇Sgroup = Rgroup
行,如果transactionID
任何行滿足條件。 否則,我想隨機選擇一行。 對於每個transactionID
,最多一行滿足Sgroup = Rgroup
。 我怎樣才能做到這一點?
嘗試的解決方案我知道如何選擇滿足條件Sgroup = Rgroup
行,如下所示:
SELECT *
FROM Transaction
WHERE Sgroup = Rgroup;
+---------------+--------+--------+
| transactionID | Sgroup | Rgroup |
+---------------+--------+--------+
| 2 | B | B |
+---------------+--------+--------+
如果不滿足條件,我也知道如何隨機選擇一行(感謝這個問題 ):
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 |
+---------------+--------+--------+
如何將這兩個表達式合並為一個? 我嘗試使用CASE表達式我沒有達到目標。 有人可以提出解決方案嗎?
示例代碼以下是生成表的代碼:
CREATE DATABASE MinimalExample;
USE MinimalExample;
CREATE TABLE Transaction (
transactionID int,
Sgroup nvarchar(1),
Rgroup nvarchar(1)
);
INSERT INTO Transaction VALUES
(1,'A','I'),
(1,'A','J'),
(2,'B','B'),
(2,'B','K');
我認為變量可能是最簡單的解決方案,如果你的意思是“隨機”:
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;
如果用“隨機”表示“任意”,你可以使用這個快速而骯臟的技巧:
(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 *
with group by
,這是我強烈反對在幾乎所有情況下使用的東西。 但是,在這種情況下,您特意嘗試將每個組縮減為不確定的行,因此它看起來並不那么糟糕。 我會注意到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()
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.