我有2张桌子。
ContactID pk
EmailAddress
FirstName
LastName
Address
OrderID pk
ContactID fk
我想获取联系人中每个电子邮件地址的号码或订单,如下所示
select
Contacts.EmailAddress,
count(distinct Orders.OrderID) AS NumOrders
from
Contacts inner join Orders on Contacts.ContactID = Orders.ContactID
group by
Contacts.EmailAddress
问题是,我还想要名字,姓氏,地址。但我无法按此分组,因为“联系人”中的每个电子邮件地址都可能具有与之关联的不同的名字,姓氏或地址。
即:
myname@email.com,Fred,Jackson,123 Main St
myname@email.com,Bob,Smith,456 Spruce St。
如何更改查询,以便获取该电子邮件地址的“通讯录”中最新条目的名字,姓氏和地址?
提前致谢!
答案 0 :(得分:0)
试试这个:
select
Contacts.Name,
Contacts.FirstName,
Contacts.LastName
Contacts.EmailAddress,
count(distinct Orders.OrderID) AS NumOrders
from
(
select max(ContactID) as ContactID,
EmailAddress
from Contacts
group by EmailAddress
) MinContactForEachEMailAddress
inner join
Contacts
on MinContactForEachEMailAddress.ContactID = Contacts.ContactID
inner join
Orders
on Contacts.ContactID = Orders.ContactID
group by
Contacts.EmailAddress
答案 1 :(得分:0)
我的第一个想法是使用窗口函数。
SELECT EmailAddress,
FirstName,
Lastname,
[Address],
EmailOrderCount
FROM (SELECT c.EmailAddress,
c.FirstName,
c.LastName,
c.[Address],
COUNT(o.OrderID) OVER (PARTITION BY c.EmailAddress) EmailOrderCount,
ROW_NUMBER() OVER (PARTITION BY c.EmailAddress ORDER BY c.ContactID DESC) Rn
FROM Contacts c
JOIN Orders o ON c.ContactID = o.ContactID
) t
WHERE Rn = 1
另一种方法是使用CROSS APPLY将前1个联系人记录附加到摘要行。
SELECT c.EmailAddress,
COUNT(o.OrderID) NumOrders,
ca.FirstName,
ca.LastName,
ca.[Address]
FROM Contacts c
INNER JOIN Orders ON c.ContactId = o.ContactID
CROSS APPLY (
SELECT TOP 1
FirstName,
Lastname,
[Address]
FROM Contacts c2
WHERE c2.EmailAddress = c.EmailAddress
ORDER BY c2.ContactID DESC) ca
GROUP BY c.EmailAddress,
ca.FirstName,
ca.LastName,
ca.[Address]
答案 2 :(得分:0)
一种简单的方法是将原始查询作为子查询并从中进行选择。我做了一些小改动,因为按主键分组比使用电子邮件地址更好。 (可以肯定的是,每个联系人只有一个电子邮件地址,并且基本意图是按人分组吗?)如果是这样,请尝试:
SELECT DISTINCT c.EmailAddress, c.FirstName, c.LastName, c.Address, sub.NumOrders
FROM
(
select
Contacts.ContactID
count(distinct Orders.OrderID) AS NumOrders
from
Contacts inner join Orders on Contacts.ContactID = Orders.ContactID
group by
Contacts.ContactID
) sub
JOIN Contacts c
ON sub.ContactID = c.ContactID
如果您确实需要通过电子邮件地址进行分组,请将上述子查询更改为原始查询,并将c.EmailAddress更改为sub.EmailAddress。当然,您可以订购最适合您的SELECT字段。
编辑如下:
ContactID必须是序列号,您可以不断将同一个人放在表格中。因此,如果您在外部查询中添加DISTINCT关键字,我相信它会为您提供所需的内容。
答案 3 :(得分:0)
获得所需内容的另一种方法是使用CTE并使用ROW_NUMBER取“最大”行。
;WITH CTE AS (
SELECT C.ContactId, C.Name, C.FirstName, C.LastName, C.EmailAddress,
ROW_NUMBER() OVER (PARTITION BY EmailAddress ORDER BY ContactId DESC) RowNo
FROM Contact C
)
SELECT CTE.*, COUNT(o.OrderID) OVER (PARTITION BY CTE.EmailAddress) Cnt
FROM CTE
JOIN Orders O on CTE.ContactID = O.ContactID
-- select the "maximum" row
WHERE CTE.RowNo = 1