簡體   English   中英

如何根據SQL中的條件選擇組中的行?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM