以下查询删除重复项:
SELECT DISTINCT Relevant.PropertyID, ACC.TenancyStartDate, ACC.AccountID, ACC.TenancyType
FROM DimAccount AS ACC RIGHT OUTER JOIN
(SELECT DISTINCT PropertyID, MAX(TenancyStartDate) AS Tenancystart
FROM DimAccount
WHERE (AccountStatus = 'Current')
GROUP BY PropertyID, TenancyStartDate) AS Relevant ON ACC.PropertyID = Relevant.PropertyID AND ACC.TenancyStartDate = Relevant.Tenancystart
GROUP BY Relevant.PropertyID, ACC.TenancyStartDate, ACC.AccountID, ACC.TenancyType, ACC.TenancyType
根据我的理解(以及我想要发生的事情),括号中的查询是选择属性ID以及状态为当前返回最高租期开始日期(尽管数次)的属性ID。然后通过开始日期和属性id将其连接到原始表,以获取最新的租赁类型。
为什么它仍然会返回重复的行!?
(顺便说一句,这与我昨天的另一个问题有关,但显然回复不应该进入对话,所以我想我会把它分开......我希望这是正确的做法......我已经搜索过但很明显我对某些事物的理解缺少了一些东西!)
答案 0 :(得分:0)
首先,使用select distinct
时几乎不需要group by
。
查询的问题是子查询中的group by
子句。
SELECT Relevant.PropertyID, ACC.TenancyStartDate, ACC.AccountID, ACC.TenancyType
FROM DimAccount ACC RIGHT OUTER JOIN
(SELECT PropertyID, MAX(TenancyStartDate) AS Tenancystart
FROM DimAccount
WHERE (AccountStatus = 'Current')
GROUP BY PropertyID
) Relevant
ON ACC.PropertyID = Relevant.PropertyID AND
ACC.TenancyStartDate = Relevant.Tenancystart
GROUP BY Relevant.PropertyID, ACC.TenancyStartDate, ACC.AccountID, ACC.TenancyType;
它不应该有TenancyStartDate
。此外,您的外部查询在ACC.TenancyType
中有两次group by
。
也就是说,使用分析函数编写查询更容易:
select a.*
from (select a.*,
max(tenancystartdate) over (partition by propertyid) as max_tsd
from dimaccount a
where accountstatus = 'Current'
) a
where tenancystartdate = max_tsd;
与您的查询完全相同,因为您的查询会考虑非当前记录。但我猜这可能是出于此目的。
答案 1 :(得分:0)
回答你的问题:是的,你是对的,没有重复。而且我很确定没有。我也很确定你的查询不符合你的想法。
这是你的派生表:
SELECT DISTINCT PropertyID, MAX(TenancyStartDate) AS Tenancystart
FROM DimAccount
WHERE (AccountStatus = 'Current')
GROUP BY PropertyID, TenancyStartDate
当您按PropertyID和TenancyStartDate进行分组时,每个PropertyID和TenancyStartDate会获得一行。对于每个这样的行,您需要MAX(TenancyStartDate),当然这是TenancyStartDate本身。您没有聚合的其他字段,因此您根本不进行聚合,而只是使行不同,对于哪个行将使用DISTINCT。然后你使用DISTINCT获取唯一的结果记录,但是你的记录已经是独一无二的,你的模糊方式就是这样做了。所以你说:选择不同记录的不同记录。您的子查询可以重写为:
SELECT DISTINCT PropertyID, TenancyStartDate
FROM DimAccount
WHERE AccountStatus = 'Current'
然后你外连接DimAccount表。因此,即使没有匹配的DimAccount记录,您也会保留已找到的记录。但是:你从DimAccount中选择了,所以当然至少有一个你已经找到的记录。您的外部联接实际上是内部联接。然后,显示的派生查询中唯一的字段是PropertyID,它始终等于ACC.PropertyID。这意味着:您只是从ACC中选择记录,而派生表只是为了确保PropertyID和TenancyStartDate的“当前”记录存在。因此,您的查询可以重写为:
SELECT DISTINCT
PropertyID, TenancyStartDate, AccountID, TenancyType
FROM DimAccount AS ACC
WHERE EXISTS
(
SELECT *
FROM DimAccount CurrentAccount
WHERE CurrentAccount.AccountStatus = 'Current'
AND CurrentAccount.PropertyID = ACC.PropertyID
AND CurrentAccount.TenancyStartDate = ACC.TenancyStartDate
);
如果PropertyID + TenancyStartDate + AccountID + TenancyType是唯一的(AccountID是表的ID?),那么您甚至可以删除DISTINCT。
此查询首先获取所有“当前”DimAccount记录,然后为您提供具有相同PropertyID和TenancyStartDate的所有记录。但是,根据您的解释,您似乎想要为每个PropertyID选择最新'当前'DimAccount记录。这完全不同于此。这种任务有不同的解决方案,具体取决于您使用的dbms(您没有在标签中指定自己的。)