简体   繁体   中英

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

I have a view with this information:

TableA (IDTableA, IDTableB, IDTableC, Active, date, ...)

For each register in TableA and each register in tableC , I want the register of tableB that have the max date and is active.

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.

I know that in theory the first query in the SQLite shouldn't work, but do it.

How can I do this query in 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 .

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.

Long story short - if you want this to work in MSSQL, adhere to SQL92 requirement.

This query in 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

;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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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