简体   繁体   English

T-SQL,如何通过查询进行分组?

[英]T-SQL, how to do this group by query?

I have a view with this information: 我对此信息有看法:

TableA (IDTableA, IDTableB, IDTableC, Active, date, ...) TableA (IDTableA,IDTableB,IDTableC,活动,日期等)

For each register in TableA and each register in tableC , I want the register of tableB that have the max date and is active. 对于TableA每个寄存器和tableC每个寄存器,我希望tableB的寄存器具有最大日期并处于活动状态。

select IDTableA, IDtableC, IDTableB, Date, Active
from myView
where Active = 1
group by IDTableA, IDTableC
Having Max(Date)
order by IDTableA;

This query works with SQLite , but if I try this query in SQL Server I get an error that say that IDTableB in the select is not contained in the group clause. 该查询与SQLite ,但是如果我在SQL Server尝试此查询, IDTableB收到一条错误消息,指出select子句中的IDTableB不包含在group子句中。

I know that in theory the first query in the SQLite shouldn't work, but do it. 我知道,从理论上讲,SQLite中的第一个查询不起作用,但可以这样做。

How can I do this query in SQL Server? 如何在SQL Server中执行此查询?

Thanks. 谢谢。

According to SQL 92, if you use GROUP BY clause, then in SELECT output expression list you can only use columns mentioned in GROUP BY list, or any other columns but they must be wrapped in aggregate functions like count() , sum() , avg() , max() , min() and so on . 根据SQL 92,如果使用GROUP BY子句,则在SELECT输出表达式列表中,您只能使用GROUP BY列表中提到的列或任何其他列,但必须将它们包装在诸如count()sum()聚合函数中。 avg()max()min() 等等

Some servers like MSSQL, Postgres are strict about this rule, but for example MySQL and SQLite are very relaxed and forgiving - and this is why it surprised you. 某些服务器(例如MSSQL,Postgres)对此规则非常严格,但是例如MySQL和SQLite则非常放松和宽容-这就是为什么它令您感到惊讶。

Long story short - if you want this to work in MSSQL, adhere to SQL92 requirement. 长话短说-如果您希望它在MSSQL中工作,请遵守SQL92要求。

This query in SQLServer SQLServer中的此查询

select IDTableA, IDtableC, IDTableB, Date, Active
from myView v1
where Active = 1
  AND EXISTS (
              SELECT 1
              FROM myView v2
              group by v2.IDTableA, v2.IDTableC
              Having Max(v2.Date) = v1.Date
              )
order by v1.IDTableA;

OR 要么

Also in SQLServer2005+ you can use CTE with ROW_NUMBER 同样在SQLServer2005 +中,您可以将CTE与ROW_NUMBER一起使用

;WITH cte AS
 (              
  select IDTableA, IDtableC, IDTableB, [Date], Active,
         ROW_NUMBER() OVER(PARTITION BY IDTableA, IDTableC ORDER BY [Date] DESC) AS rn
  from myView v1
  where Active = 1
  )
  SELECT *
  FROM cte
  WHERE rn = 1
  ORDER BY IDTableA

Try this, 尝试这个,

select * from table1 b
where active = 1
and date = (select max(date) from table1
            where idtablea = b.idtablea
            and idtablec = b.idtablec
            and active = 1);

SQLFIDDLE DEMO SQLFIDDLE演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM