我有一个表格,其数据类似于以下内容。
我一直在使用一个包含大量行的大表,其中包含不同的标志和键。我设法将它们分组,以便我在标志为真的位置最低,并且标志为假的最低位置。
╔══════════════════╦══════╦═══════╗
║ Email ║ Flag ║ Key ║
╠══════════════════╬══════╬═══════╣
║ email1@one.com ║ 1 ║ 77731 ║
║ email1@one.com ║ 0 ║ 67980 ║
║ email2@two.com ║ 1 ║ 64417 ║
║ email2@two.com ║ 0 ║ 71733 ║
║ email3@three.com ║ 1 ║ 95655 ║
║ email4@four.com ║ 0 ║ 91016 ║
╚══════════════════╩══════╩═══════╝
现在,对于每个不同的电子邮件,如果存在真正的AND错误标志,我想返回 true 键值。否则,我想返回最低值。
所以输出理想情况如下:
╔══════════════════╦══════╦═══════╗
║ Email ║ Flag ║ Key ║
╠══════════════════╬══════╬═══════╣
║ email1@one.com ║ 1 ║ 77731 ║
║ email2@two.com ║ 1 ║ 64417 ║
║ email3@three.com ║ 1 ║ 95655 ║
║ email4@four.com ║ 0 ║ 91016 ║
╚══════════════════╩══════╩═══════╝
我一直在尝试各种分组,有条款,使用前两个中的案例陈述,但无法看到如何做到这一点。
如果有帮助,我只需要电子邮件和密钥。
答案 0 :(得分:1)
有很多方法,这里有两个。
方法1
你可以用这样的CTE来做:
WITH data_cte AS (
SELECT Email, MAX(CAST(Flag AS INT)) AS Flag
FROM Data
GROUP BY Email)
SELECT Data.*
FROM data_cte
JOIN Data
ON Data.Email = data_cte.Email
AND Data.Flag = data_cte.Flag
要解构它,CTE部分只会为每封电子邮件获取MAX
标记值(需要CAST
到INT
,因为您不能MAX
在BIT
列上,查询的其余部分将CTE连接回表以获取相关数据行。
方法2
使用UNION
:
SELECT *
FROM Data
WHERE Flag = 1
UNION
SELECT *
FROM Data
WHERE Flag = 0
AND NOT EXISTS(SELECT *
FROM Data AS InnerData
WHERE InnerData.Flag = 1
AND InnerData.Email = Data.Email)
答案 1 :(得分:0)
SELECT
A.Email
,CASE WHEN A.Cf > A.Sf THEN Mk ELSE Key END AS ChosenKey
FROM
(
SELECT
Email
,Key
,COUNT(Flag) Cf
,MIN(Key) OVER(PARTITION BY Email ORDER BY Key ASC) AS Mk
,SUM(Flag) OVER(PARTITION BY Email) Sf
FROM
Table
) AS A
也许可以从这样的事情开始工作?然后删除你的副本等。
答案 2 :(得分:0)
你也可以通过窗口函数来实现这个目的:
SELECT email, flag, key FROM (
SELECT email, flag, key, ROW_NUMBER() OVER ( PARTITION BY email ORDER BY flag DESC ) AS rn
FROM mytable
) x1
WHERE rn = 1;