2009-05-19 12 views
0

Cela a été résolu. L'instruction était dans une autre partie de la procédure stockée.SQL - Sélection du Top 1 avec ordre par?

La procédure stockée J'écris ne me permet pas de le faire:

declare @dtTopDate datetime 
    select top 1 @dtTopDate = date_build 
    from database..table 
    where database..table.parent = @Parent 
    and database..table.child = @Child 
    order by date_build desc 

me donne cette erreur:

Column "database..table.date_build" is invalid in the ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause.

Qu'est-ce que je fais mal?

[Modifier] Il n'y a pas de déclaration de groupe par ici. SQL2005.

est ici un peu plus le contexte:

if @Notify = 0 
begin 
    declare @dtTopDate datetime 
     select top 1 @dtTopDate = date_build 
     from database..table 
     where database..table.parent = @Parent 
     and database..table.child = @Child 
     order by date_build desc 

     insert 
     into database2..table 
      (parent, child, notification_date, change_date) 
     values (@Parent, @Child, @dtTopDate, getdate()) 
    return 
end 
+0

Pouvez-vous afficher les définitions de table, le contenu de @Parent et @Child, et le logiciel de base de données que vous utilisez – Andomar

+0

donc il n'y a pas clause GROUP BY votre st atement? Êtes-vous sûr de cela? – spender

+0

Je remarque que vous avez à la fois @dtTopDate et @dtLatestDate. Est-ce intentionnel? –

Répondre

1

Le problème résidait dans une autre partie de la procédure stockée. J'utilisais un compte (*) ailleurs et il fallait un groupe par. Merci pour l'aide.

1

Quelle version de SQL utilisez-vous? Cela fonctionne bien pour MS SQL Server 2005 (par exemple, je corrige la déclaration).

0

SELECT Essayez @dtLatestDate = TOP 1 date_build ...

+0

-1 Erreur de syntaxe – Andomar

+0

Oui.Aurait dû vérifier avant de suggérer. ;) –

1

Honnêtement la seule chose que je peux voir que le mal est @dtTopDate =/= @dtLatestDate En dehors de cela, il n'y a pas de groupe PAR clause votre instruction SQL.

Je viens de courir ça et ça a bien fonctionné.

declare @OrderDate datetime 

select top 1 @OrderDate = OrderDate 
from Orders 
where Orders.CustomerID = 'ALFKI' 
and Orders.EmployeeID = 4 
order by OrderDate desc 

SELECT @OrderDate 
1

Essayez de qualifier les colonnes correctement afin d'éviter toute ambiguïté ou schéma x-base de données numéro

declare @dtTopDate datetime 

select top 1 
    @dtTopDate = [database]..[table].date_build 
FROM 
    [database]..[table] 
where 
    [database]..[table].parent = @Parent 
    and [database]..[table].child = @Child 
order by 
    [database]..[table].date_build desc 

Ou alias il

declare @dtTopDate datetime 

select top 1 
    @dtTopDate = foo.date_build 
FROM 
    [database]..[table] foo 
where 
    foo.parent = @Parent 
    and foo.child = @Child 
order by 
    foo.date_build desc 
2

Cela fonctionne pour moi, mais je ne suis pas sûr si c'est ce que vous essayez de faire b/c votre exemple a quelques erreurs.

use Test 
go 
CREATE TABLE [dbo].[MyTable] 
(
    [MyTableId] [uniqueidentifier] NOT NULL, 
    [MyDate] [datetime] NOT NULL, 
    CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED([MyTableId] ASC,[MyDate] ASC) 
) 
GO 
CREATE PROCEDURE ProcTopDate 
(
    @MyDate datetime OUT 
) 
AS 
BEGIN 
    SET NOCOUNT ON; 

    SELECT TOP 1 
     @MyDate = [MyDate] 
    FROM [Test].[dbo].[MyTable] 
    order by MyDate 
END 
GO 

insert into MyTable(MyTableId, MyDate) 
values(newid(), getdate()) 
go 

declare @MyDate datetime 
exec ProcTopDate @MyDate OUT 
print @MyDate 
2

Au lieu de SELECT TOP 1 ... ORDER BY ...

Pourquoi ne pas essayer SELECT MAX (..

DECLARE @dtTopDate datetime 
SELECT @dtTopDate = MAX(date_build) 
from database..table 
where database..table.parent = @Parent 
and database..table.child = @Child 
0

si vous voulez vraiment difficile, en T-SQL, vous pouvez essayez d'utiliser la méthode row_number() et une sélection intérieure:

select * from 
(
    select 
     db.groupId 
     , db.date_build 
     , date_build_rank = row_number() over (partition by db.groupId order by db.date_build desc) 
    from 
     #date_build_tbl db 
) as a 
where a.date_build_rank < 2;