我的表格列如下:
<li class="first-child">
<a href="i.CityUrl">
i.Name
</a>
</li>
此表包含用户的银行详细信息历史记录。如果用户在我们的系统中更改其银行详细信息,则会在此表中插入一个新行。
我正在尝试创建一个查询,该查询将显示已在两个日期之间更改其详细信息的用户,并且可能在这些日期之间更改了一定次数。例如,显示已在| ID | UserID | AccountName | SortCode (encrypted) | AccountNumber (encrypted) | DateAdded
和2016-01-01
之间更改其详细信息的用户至少2次。
在两个日期之间进行选择是微不足道的,但我正在努力将#34;至少#times&#34;纳入其中。此外,每个用户的第一条记录不应包含在结果中,因为此记录是用户首次添加其银行详细信息(因此不会更改其银行详细信息)。
答案 0 :(得分:3)
true
答案 1 :(得分:1)
先按用户分组,然后选择用户
SELECT * FROM Table t2
WHERE t2.UserId IN (
SELECT t1.UserId
FROM Table t1
WHERE t1.DateAdded BETWEEN 'start_date' AND 'end_date'
GROUP BY t1.UserId
HAVING COUNT(*) >= 2
) AND t2.DateAdded BETWEEN 'start_date' AND 'end_date'
编辑(戈登):
我认为子查询回答了OP的问题:
SELECT t1.UserId
FROM Table t1
WHERE t1.DateAdded BETWEEN $start_date AND $end_date
GROUP BY t1.UserId
HAVING COUNT(*) >= 2;
Niyoko的答案更进了一步,获得了原始的详细记录。
我在最后一段中错过了要求。要排除每个用户的第一行,请使用以下SQL
SELECT t1.UserId
FROM Data t1
WHERE t1.DateAdded BETWEEN '2015-01-01' AND '2015-01-06'
AND t1.Id <> (SELECT Id FROM Data t2 WHERE t1.UserId = t2.UserId ORDER BY DateAdded LIMIT 1)
GROUP BY t1.UserId
HAVING COUNT(*) >= 2;
答案 2 :(得分:0)
使用提供的答案,我能够提出一个不需要对ID列进行排序的解决方案,并且在相当大的数据集中似乎非常有效。我最终使用的SQL是在下面。它确实创建了一些临时表,但似乎是我找到的最快的解决方案。我还要注意,这个SQL没有包含我需要的“最小出现次数”要求。我在PHP而不是SQL中实现了这个要求,因为SQL需要大量重复才能满足要求。
SELECT *
FROM UserBankDetails AS bd
LEFT JOIN (
SELECT ID
FROM UserBankDetails
WHERE (UserID, DateAdded) IN (
SELECT UserID, MIN(DateAdded)
FROM UserBankDetails
GROUP BY UserID
)
) AS temp ON bd.ID = temp.ID
WHERE temp.ID IS NULL
AND bd.DateAdded BETWEEN '2015-01-01' AND '2015-12-01'
ORDER BY bd.UserID, bd.DateAdded
困难在于有效地排除了每个用户的最早记录。此解决方案为每个用户创建一个包含MIN DateAdded
的临时表,然后使用left exclusion join
从最终结果集中排除这些记录。
如上所述,我没有纳入“最低出现次数”要求,但是,这可以这样做(看看它有多详细):
SELECT *
FROM UserBankDetails AS bd
LEFT JOIN (
SELECT ID
FROM UserBankDetails
WHERE (UserID, DateAdded) IN (
SELECT UserID, MIN(DateAdded)
FROM UserBankDetails
GROUP BY UserID
)
) AS temp ON bd.ID = temp.ID
WHERE temp.ID IS NULL
AND bd.DateAdded BETWEEN '2015-01-01' AND '2015-12-01'
AND bd.UserID IN (
SELECT UserID
FROM UserBankDetails AS bd1
LEFT JOIN (
SELECT ID
FROM UserBankDetails
WHERE (UserID, DateAdded) IN (
SELECT UserID, MIN(DateAdded)
FROM UserBankDetails
GROUP BY UserID
)
) AS temp1 ON bd1.ID = temp1.ID
WHERE temp1.ID IS NULL
AND bd1.DateAdded BETWEEN '2015-01-01' AND '2015-12-01'
GROUP BY UserID
HAVING COUNT(*) > 1
)
ORDER BY bd.UserID, bd.DateAdded