基于SQL筛选行而不使用Group by

基于SQL筛选行而不使用Group by,sql,sql-server,group-by,partition-by,Sql,Sql Server,Group By,Partition By,我有一个查询,它将对6个表执行连接,并根据条件获取不同的列。我想添加一个额外的筛选条件,该条件将只为那些计数(不同日期捕获)大于30的成员提供。我可以使用groupby和having获得满足此条件的成员列表。但我不想按其他列名分组,因为这是一个条件。在这种情况下,我是否需要使用分区依据 样本表a +-----+------------+--------------+ | Id | Identifier | DateCaptured | +-----+------------+---------

我有一个查询,它将对6个表执行连接,并根据条件获取不同的列。我想添加一个额外的筛选条件,该条件将只为那些计数(不同日期捕获)大于30的成员提供。我可以使用
groupby
having
获得满足此条件的成员列表。但我不想按其他列名分组,因为这是一个条件。在这种情况下,我是否需要使用分区依据

样本表a

+-----+------------+--------------+
| Id  | Identifier | DateCaptured |
+-----+------------+--------------+
| 1   |      05548 | 2017-09-01   |
| 2   |      05548 | 2017-09-01   |
| 3   |      05548 | 2017-09-01   |
| 4   |      05548 | 2017-09-02   |
| 5   |      05548 | 2017-09-03   |
| 6   |      05548 | 2017-09-04   |
| 7   |      37348 | 2017-08-15   |
| 8   |      37348 | 2017-08-15   |
| .   |            |              |
| .   |            |              |
| .   |            |              |
| 54  |      37348 | 2017-10-15   |
+-----+------------+--------------+
查询

SELECT  a.value,
        b.value, c.value,
        d.value
        FROM Table a
    INNER JOIN Table b on a.Id=b.id
    INNER JOIN Table c on a.Id=c.Id and s.Invalid=0
    INNER JOIN Table d on a.Id=d.Id 
假设表a有30多条标识符记录
37348
。如何为上述查询仅获取此标识符

这些是我对上述选择感兴趣的患者

SELECT  a.Identifier,count(DISTINCT DateCaptured)
    FROM Table a
    INNER JOIN Table b on a.Id=b.id
    INNER JOIN Table c on a.Id=c.Id and s.Invalid=0
    INNER JOIN Table d on a.Id=d.Id 
    GROUP BY Identifier
    HAVING count(DISTINCT DateCaptured)>30

如果多行确实在
表A
中,则可以执行以下操作:

SELECT a.value, b.value, c.value, d.value
FROM (SELECT a.*, COUNT(*) OVER (PARTITION BY id) as cnt
      FROM a
     ) a INNER JOIN
     b 
     ON a.Id = b.id INNER JOIN 
     c 
     ON a.Id = c.Id AND s.Invalid = 0 INNER JOIN 
     d 
     ON a.Id = d.Id
WHERE a.cnt > 30;
SELECT a.value, b.value, c.value, d.value
FROM (SELECT a.*, SUM(CASE WHEN seqnum = 1 THEN 1 ELSE 0 END) OVER (PARTITION BY id) as cnt
      FROM (SELECT a.*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY DateCaptured) as seqnum
            FROM a
           ) a
     ) a INNER JOIN
     b 
     ON a.Id = b.id INNER JOIN 
     c 
     ON a.Id = c.Id AND s.Invalid = 0 INNER JOIN 
     d 
     ON a.Id = d.Id
WHERE a.cnt > 30;
注意:如果您仍然需要计数(不同),您可以执行以下操作:

SELECT a.value, b.value, c.value, d.value
FROM (SELECT a.*, COUNT(*) OVER (PARTITION BY id) as cnt
      FROM a
     ) a INNER JOIN
     b 
     ON a.Id = b.id INNER JOIN 
     c 
     ON a.Id = c.Id AND s.Invalid = 0 INNER JOIN 
     d 
     ON a.Id = d.Id
WHERE a.cnt > 30;
SELECT a.value, b.value, c.value, d.value
FROM (SELECT a.*, SUM(CASE WHEN seqnum = 1 THEN 1 ELSE 0 END) OVER (PARTITION BY id) as cnt
      FROM (SELECT a.*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY DateCaptured) as seqnum
            FROM a
           ) a
     ) a INNER JOIN
     b 
     ON a.Id = b.id INNER JOIN 
     c 
     ON a.Id = c.Id AND s.Invalid = 0 INNER JOIN 
     d 
     ON a.Id = d.Id
WHERE a.cnt > 30;

如果多行确实在
表A
中,则可以执行以下操作:

SELECT a.value, b.value, c.value, d.value
FROM (SELECT a.*, COUNT(*) OVER (PARTITION BY id) as cnt
      FROM a
     ) a INNER JOIN
     b 
     ON a.Id = b.id INNER JOIN 
     c 
     ON a.Id = c.Id AND s.Invalid = 0 INNER JOIN 
     d 
     ON a.Id = d.Id
WHERE a.cnt > 30;
SELECT a.value, b.value, c.value, d.value
FROM (SELECT a.*, SUM(CASE WHEN seqnum = 1 THEN 1 ELSE 0 END) OVER (PARTITION BY id) as cnt
      FROM (SELECT a.*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY DateCaptured) as seqnum
            FROM a
           ) a
     ) a INNER JOIN
     b 
     ON a.Id = b.id INNER JOIN 
     c 
     ON a.Id = c.Id AND s.Invalid = 0 INNER JOIN 
     d 
     ON a.Id = d.Id
WHERE a.cnt > 30;
注意:如果您仍然需要计数(不同),您可以执行以下操作:

SELECT a.value, b.value, c.value, d.value
FROM (SELECT a.*, COUNT(*) OVER (PARTITION BY id) as cnt
      FROM a
     ) a INNER JOIN
     b 
     ON a.Id = b.id INNER JOIN 
     c 
     ON a.Id = c.Id AND s.Invalid = 0 INNER JOIN 
     d 
     ON a.Id = d.Id
WHERE a.cnt > 30;
SELECT a.value, b.value, c.value, d.value
FROM (SELECT a.*, SUM(CASE WHEN seqnum = 1 THEN 1 ELSE 0 END) OVER (PARTITION BY id) as cnt
      FROM (SELECT a.*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY DateCaptured) as seqnum
            FROM a
           ) a
     ) a INNER JOIN
     b 
     ON a.Id = b.id INNER JOIN 
     c 
     ON a.Id = c.Id AND s.Invalid = 0 INNER JOIN 
     d 
     ON a.Id = d.Id
WHERE a.cnt > 30;

…这取决于您希望输出的外观,以及您开始时的条件。当然,您可以在任何表上聚合
DateCaptured
,但还不清楚是否需要首先减少已计数的行(即,还必须在其他一些表中有一个引用)。如果除计数外,还显示每个日期,则窗口计数非常有用。您使用的SQL server版本是什么?@Clockwork Muse的输出与第一个查询相同。计数(截然不同的数据包)> 30只是一个过滤条件,只考虑那些“代码>标识符< /代码>,它们有30个以上的区别。dates@Sparrow2008 R2…这取决于您希望输出是什么样子,以及开始时的条件。当然,您可以在任何表上聚合
DateCaptured
,但还不清楚是否需要首先减少已计数的行(即,还必须在其他一些表中有一个引用)。如果除计数外,还显示每个日期,则窗口计数非常有用。您使用的SQL server版本是什么?@Clockwork Muse的输出与第一个查询相同。计数(截然不同的数据包)> 30只是一个过滤条件,只考虑那些“代码>标识符< /代码>,它们有30个以上的区别。dates@Sparrow看起来,获取所需患者的OP查询过于复杂+1获取所需患者的OP查询等工具过于复杂+1.