如何获得必须具有不同条件的数据?

时间:2016-01-11 13:09:33

标签: sql sql-server database sql-server-2012 subquery

如果我的表格具有以下结构:

用户: USERIDNAME

TIMETB: CHECKTIMESysdatemodifiedUSERID

如果我有这样的样本数据:

用户:

   USERID    NAME
    434      moh
    77       john
    66       yara

TIMETB:

CHECKTIME              USERID  modified
2015-12-21 07:20:00.000  434      0
2015-12-21 08:39:00.000  434      2
2015-12-22 07:31:00.000  434      0
2015-12-21 06:55:00.000  77       0
2015-12-21 07:39:00.000  77       0
2015-12-25 07:11:00.000  66       0
2015-12-25 07:22:00.000  66       0
2015-12-25 07:50:00.000  66       2
2015-12-26 07:40:00.000  66       2
2015-12-26 07:21:00.000  66       2

现在我希望获得在同一天进行two or more different次交易(已修改)的用户:

我期望的结果是:

CHECKTIME               USERID  modified  NAME
2015-12-21 07:20:00.000  434      0       moh
2015-12-21 08:39:00.000  434      2       moh
2015-12-25 07:11:00.000  66       0       yara
2015-12-25 07:22:00.000  66       0       yara
2015-12-25 07:50:00.000  66       2       yara

我写下面的查询,但我得到的比我预期的更多我的意思是我得到的交易相同(修改)的用户!!。

SELECT a.CHECKTIME,
       a.Sysdate,
       (CASE WHEN a.modified = 0 THEN 'ADD' ELSE 'DELETE' END) AS modified,
       b.BADGENUMBER,
       b.name,
       a.Emp_num AS Creator
FROM TIMETB a
INNER JOIN Users b ON a.USERID = b.USERID
WHERE YEAR(checktime) = 2015
    AND MONTH(checktime) = 12
    AND (
        SELECT COUNT(*)
        FROM TIMETB cc
        WHERE cc.USERID = a.USERID
            AND CONVERT(DATE, cc.CHECKTIME) = CONVERT(DATE, a.CHECKTIME)
            AND cc.modified IN (0, 2)
    ) >= 2
    AND a.modified IS NOT NULL
    AND a.Emp_num IS NOT NULL

1 个答案:

答案 0 :(得分:1)

您可以使用窗口函数:

select t.*
from (select t.*,
             count(*) over (partition by userid, cast(checktime as date)) as cnt
      from timetb t
     ) t
where cnt >= 2;

如果您想要名称,只需加入相应的表格即可。

编辑:

如果您想要不同的列值,一种简单的方法是比较最小值和最大值:

select t.*
from (select t.*,
             min(modified) over (partition by userid, cast(checktime as date)) as minm,
             max(modified) over (partition by userid, cast(checktime as date)) as maxm
      from timetb t
     ) t
where minm <> maxm;