我知道这必须在SQL 101中,但我需要返回一行,其中一列包含X和Y,其中ID是重复的。
示例表。
ACCOUNT | Activity
-------------------------
1 | Email
1 | Appointment
2 | Email
2 | Email
3 | Email
3 | Appointment
我需要只返回帐号1和3的SQL,如下所示:
ACCOUNT | Activity
-------------------------
1 | Email
1 | Appointment
3 | Email
3 | Appointment
在伪代码中它是(WHERE ID同时出现'约会'和'电子邮件')
不应该返回帐户2,因为表格中没有行WHERE Account = 2 AND Activity ='Appointment'。
我希望这是有道理的,并且非常感谢您的意见。
提前感谢。
编辑线以下
感谢大家的建议,我非常喜欢@rafa建议使用count distinct,但当然查询比最初建议的更复杂。第一个表实际上是来自另一个查询的结果集,下面的查询包括@rafa建议,但查询不起作用,我理解我需要调用子查询,但我不确定在哪里或如何,再次感谢:
SELECT T.ACCOUNT, T.COMPANY, H.RESPONSE, H.DAT_ AS Resp_Date, H.USERNAME, (date_format(P.ENDDATE,'%M')) AS Renewal, T.OWNER, COUNT(DISTINCT(H.ACTIVITY)) AS Dis_Act, H.CustomerStatus, H.Contact, A.ANAL14 AS APPDATE
FROM TELRCMxxx T LEFT JOIN TELCOMxxx H ON T.ACCOUNT = H.ACCOUNT LEFT JOIN ACCSTOxxx P ON T.ACCOUNT = P.ACCOUNT LEFT JOIN RCMANLxxx A ON T.ACCOUNT = A.ACCOUNT
WHERE (H.ACTIVITY in ('Appointment', 'email'))
Group by Account
having Dis_Act > 1
学家
谢谢大家。
答案 0 :(得分:1)
一种非常天真的方法是:
SELECT
*
FROM MyTable t1
WHERE EXISTS
(
SELECT 1 FROM MyTable WHERE ACCOUNT = t1.ACCOUNT AND Activity = 'Email'
)
AND EXISTS
(
SELECT 1 FROM MyTable WHERE ACCOUNT = t1.ACCOUNT AND Activity = 'Appointment'
)
答案 1 :(得分:0)
假设该表的名称类似于AccountActivity
:
SELECT *
FROM AccountActivity
WHERE Account IN (
SELECT AccountID
FROM AccountActivity
WHERE Activity = 'Email')
AND Account IN (
SELECT AccountID
FROM AccountActivity
WHERE Activity = 'Appointment')
答案 2 :(得分:0)
这可以通过几种方式完成。想到的第一种方法是使用Exists
子句几个关系:
Select *
From MyTable t1
Where Exists (
Select Null
From MyTable t2
Where t1.Account = t2.Account
And t2.Activity = 'Email'
)
And Exists (
Select Null
From MyTable t3
Where t1.Account = t3.Account
And t3.Activity = 'Appointment'
)
或者有几个自我加入:
Select t1.*
From MyTable t1
join MyTable t2
on t1.Account = t2.Account
and t2.Activity = 'Email'
join MyTable t3
on t1.Account = t3.Account
and t3.Activity = 'Appointment'
答案 3 :(得分:0)
这是一种方法。使用使用相关子查询的EXISTS
谓词来检查"其他"是否存在。行。这假设您只想返回值为'电子邮件'和“预约'在“活动”列中,并排除具有任何其他活动值的行。 (这不是最有效的方法。)
SELECT t.account
, t.activity
FROM example_table t
WHERE t.activity IN ('Email','Appointment')
AND EXISTS ( SELECT 1
FROM example_table d
WHERE d.account = t.account
AND d.activity =
CASE t.activity
WHEN 'Email' THEN 'Appointment'
WHEN 'Appointment' THEN 'Email'
END
)
<强> ADDITION 强>
以上是适用于原始查询的方法(后来作为另一个答案的评论提供......)
SELECT t.ACCOUNT
, t.COMPANY
, h.RESPONSE
, h.DAT_ AS Resp_Date
, h.USERNAME
, DATE_FORMAT(p.ENDDATE,'%M') AS Renewal
, t.OWNER
, h.CustomerStatus
, h.Contact
, a.ANAL14 AS APPDATE
FROM TELRCMxxx t
JOIN TELCOMxxx h
ON t.ACCOUNT = h.ACCOUNT
AND h.ACTIVITY in ('Appointment','email')
AND EXISTS
( SELECT 1
FROM TELCOMxxx b
WHERE b.ACCOUNT = h.ACCOUNT
AND b.ACTIVITY = CASE h.ACTIVITY
WHEN 'email' THEN 'Appointment'
WHEN 'Appointment' THEN 'email'
END
)
LEFT
JOIN ACCSTOxxx p
ON t.ACCOUNT = p.ACCOUNT
LEFT
JOIN RCMANLxxx a
ON t.ACCOUNT = a.ACCOUNT
注意:原始查询与h的LEFT联接,但&#34;外部&#34; WHERE子句否定了连接操作,它有效地验证了h.ACTIVITY IS NOT NULL
。删除了LEFT关键字,并将h.ACTIVITY IN ('Appointment','email')
谓词从WHERE子句移动到连接的ON子句。但这并没有改变任何关于查询的内容。
对查询的更改是添加&#34; EXISTS
&#34;谓词检查h
中是否存在另一行,匹配ACCOUNT,并匹配“约会”&#39;或者&#39;电子邮件&#39;,与被检查的h
行中的值相反。
请注意:
AND b.ACTIVITY = CASE h.ACTIVITY
WHEN 'email' THEN 'Appointment'
WHEN 'Appointment' THEN 'email'
END
相当于:
AND ( ( b.ACIVITY = 'email' AND h.ACTIVITY = 'Appointment' )
OR
( b.ACIVITY = 'Appointment' AND h.ACTIVITY = 'email' )
)
END ADDITION
如果需要返回帐户的所有行,包括活动的其他值,则从外部查询的WHERE子句中删除t.Activity IN
谓词,并检查是否存在&# 39;电子邮件&#39;和“预约&#39;该帐户的行:
SELECT t.account
, t.activity
FROM example_table t
WHERE EXISTS ( SELECT 1
FROM example_table e
WHERE e.account = t.account
AND e.activity = 'Email'
)
AND EXISTS ( SELECT 1
FROM example_table a
WHERE a.account = t.account
AND a.activity = 'Appointment'
)
这是不最有效的方法,但会返回指定的结果。
对于大型集合,(通常)更有效的方法是使用JOIN操作。
要获取具有“电子邮件”和“电子邮件”的不同帐户值的列表。和“预约&#39;行:
SELECT e.account
FROM example_table e
JOIN example_table a
ON a.account = e.account
AND a.activity = 'Appointment'
WHERE e.activity = 'Email'
GROUP BY e.account
从表中获取这些帐户的所有行:
SELECT t.account
, t.activity
FROM example_table t
JOIN ( SELECT e.account
FROM example_table e
JOIN example_table a
ON a.account = e.account
AND a.activity = 'Appointment'
WHERE e.activity = 'Email'
GROUP BY e.account
) s
ON s.account = t.account
如果您只想返回具有特定活动值的行,则可以添加WHERE子句,例如
WHERE t.activity IN ('Email','Appointment','Foo')
答案 4 :(得分:0)
使用GROUP BY
与HAVING
SELECT account, COUNT(DISTINCT(activity)) AS diff_acts
FROM account_activity
WHERE activity IN ('Appointment', 'Email')
GROUP BY account
HAVING diff_acts > 1
<强> SQL Fiddle 强>
如果您想要所有行,请按以下步骤操作
SELECT *
FROM account_activity
WHERE account IN (
SELECT account
FROM account_activity
WHERE activity IN ('Appointment', 'Email')
GROUP BY account
HAVING COUNT(DISTINCT(activity)) > 1 )
<强> SQL Fiddle 强>
答案 5 :(得分:0)
这会有用吗?
select src.account, src.activity
from
(
select account, activity, COUNT(activity) as cnt
from mytable as t1
group by account, activity
) as src
where cnt = 1
order by src.account
答案 6 :(得分:0)
简单的内部联接将起作用
select account from MyTable as T1
inner join MyTable as T2 on (T2.Account = T1.Account and T2.Activity = 'Appointment')
where T1.Activity = 'EMail'
ADDED
当然,如果性能是一个问题,Activity上的索引会很有用,但无论你如何编写查询,这都是非常有用的
答案 7 :(得分:0)
从x所在的帐户中选择帐户,活动 (从
中选择帐户(在x.account = x1.account和x.activity&lt;&gt; x1.activity中选择x.account,x1.account as account1 from x join x as x1)summary1
其中summary1.account1不为null )
不知道mysql但是这是在sybase / MS类型db中工作的通用sql。