2012-01-10 1 views
4

Je veux trouver un moyen plus efficace que ma solution. Donc, voici le problème: Je veux avoir un encart en vrac à partir d'une instruction select. (Informations générales: J'utilise MSSQL 2005)Insérer à l'exclusion de la seconde, en ajoutant le premier des enregistrements existants

Exemple de sélection:

SELECT number, amount, year, modifiedDate, itm, city, c, d, e, f.... FROM X 
JOIN Y .... 

Donc, si le résultat est

... 
Num Amount Year ModifiedDate Itm City ... ... 
1 100 2011 01-01-2011 2 Amsterdam .. .. 
1 100 2011 01-02-2011 5 Den Haag .. .. 
2 4560 2011 01-02-2011 6 Amsterdam .. .. 
33 456 2010 01-02-2011 12 Leiden .. .. 
22 456 2010 01-02-2011 12 Leiden .. .. 
.... 

Dans la destination que je veux avoir:

... 
Num Amount Year ModifiedDate Itm City ... ... 
1 100 2011 01-02-2011 5 Den Haag .. .. 
2 4560 2011 01-02-2011 6 Amsterdam .. .. 
33 456 2010 01-02-2011 12 Leiden .. .. 
22 456 2010 01-02-2011 12 Leiden .. .. 
.... 

Sans ce dossier: (1 100 2011 01-01-2011 2 Amsterdam)

Je veux insérer le premier de ces deux dans une table de destination. J'ai d'autres enregistrements provenant de la sélection qui devraient également être insérés. Donc, dans ce cas, je veux prendre le premier où le nombre, le montant et l'année sont le même ordre par modifiedDate DESC. C'est ce que je veux faire. J'ai déjà fait une solution en utilisant Cursor, mais il devrait y avoir un meilleur moyen.

+0

Je ne pense toujours pas que cela soit suffisant. S'il vous plaît montrez votre curseur afin que nous puissions voir exactement ce que vous faites. –

+1

La raison pour laquelle je ne poste pas le curseur est parce que je suis à la recherche d'une autre solution. Avec le curseur, j'ai déjà la réponse. Je me demande s'il y a un AUTRE moyen. La raison pour laquelle je ne poste pas toute la requête est parce que c'est très complexe, mais c'est l'idée fondamentalement. Je pense que maintenant devrait être explicite. Faites-moi savoir si ce n'est toujours pas clair. – Ekaterina

+0

Entre ces deux lignes, comment dites-vous le premier du second? Vous commandez des lignes par 'modifiedDate', mais ces deux-là ont des valeurs' modifiedDate' identiques. Leur ordre particulier serait, en l'absence d'autres critères de tri, arbitraire. –

Répondre

1

Si je comprends ce que vous essayez de faire correctement, je pense que vous devez regrouper sur les trois premières colonnes, et sélectionnez la valeur MAX de la colonne modifiedDate. Faites-moi savoir si j'ai mal compris.

SELECT 
     number, 
     amount, 
     year, 
     MAX(modifiedDate) 
FROM  
     X 
GROUP BY 
     number, amount, year 

Si vous êtes à la recherche aussi de l'aide sur la INSERT partie de la requête, s'il vous plaît donner plus de détails sur ce que vous faites actuellement là-bas.

+0

Oui, mon explication n'était pas si précise. J'ai ajouté quelques colonnes factices. La sélection d'origine est plus complexe avec beaucoup de colonnes qui ne sont pas identiques et d'autres qui se rejoignent ci-dessous. J'ai essayé de grouper dans la clause where, mais je n'ai toujours pas réussi à obtenir ce que je voulais. – Ekaterina

+0

Vous devriez toujours poster le code complet lorsque cela est possible. De cette façon, vous aurez plus de chances d'obtenir la réponse dont vous avez vraiment besoin, même si cela prend plus de temps à comprendre!Je suppose que ma réponse n'est pas beaucoup d'aide alors? –

+0

Certes, je voulais que ce soit plus facile à comprendre, mais je suppose que ce n'était pas le cas. Non, votre réponse n'est pas ce que je cherche. Avez-vous une idée cependant? Autre que le curseur? – Ekaterina

0

Regroupez par toutes vos colonnes pour cela.

Exemple:

--Test Data 
DECLARE @sourceTable TABLE(number int,amount int, yr int, modifiedDate datetime) 
DECLARE @destTable TABLE(number int,amount int, yr int, modifiedDate datetime) 

INSERT INTO @sourceTable (number, amount, yr, modifiedDate) VALUES (1,100,2011,'01 Jan 2011') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate) VALUES (1,100,2011,'01 Jan 2011') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate) VALUES (1,100,2011,'03 Jan 2011') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate) VALUES (1,100,2011,'02 Jan 2011') 

--Query 
INSERT INTO @destTable(number, amount, yr, modifiedDate) 
SELECT number, amount, yr, modifiedDate 
FROM @sourceTable 
GROUP BY number, amount, yr, modifiedDate 
ORDER BY modifiedDate DESC 

--Results 
SELECT * FROM @destTable 
+0

Pas ce que je cherche. J'ai un peu modifié ma question, car elle était trompeuse. J'ai un énorme choix, donc le groupe ne fonctionne pas de cette façon. – Ekaterina

+0

Pouvez-vous nous donner la table def pour la table de destination? – Mack

2

Cela devrait vous se rapprocher de ce que vous avez besoin:

DECLARE @sourceTable TABLE(number int,amount int, yr int, modifiedDate datetime, itm int, City varchar(20)) 
DECLARE @destTable TABLE(number int,amount int, yr int, modifiedDate datetime, itm int, City varchar(20)) 

INSERT INTO @sourceTable (number, amount, yr, modifiedDate, Itm, City) VALUES (1,100,2011,'01-01-2011',2,'Amsterdam') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, Itm, City) VALUES (1,100,2011,'01-02-2011',5,'Den Haag') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, Itm, City) VALUES (2,4560,2011,'01-02-2011',6,'Amsterdam') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, Itm, City) VALUES (33,456,2010,'01-02-2011',12,'Leiden') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, Itm, City) VALUES (22,456,2010,'01-02-2011',12,'Leiden') 

;WITH CTE AS 
(
    SELECT number, amount, yr, modifiedDate 
    , ROW_NUMBER() OVER (PARTITION BY number, amount, yr ORDER BY modifiedDate DESC) AS itemRank 

    FROM @sourceTable 
    GROUP BY number, amount, yr, modifiedDate 
) 
INSERT INTO @destTable (number, amount, yr, modifiedDate, Itm, City) 
SELECT st.number, st.amount, st.yr, st.modifiedDate, st.Itm, st.City 
FROM @sourceTable st 
INNER JOIN cte ON st.number = cte.number 
AND st.amount = cte.amount 
AND st.yr = cte.yr 
AND st.modifiedDate = cte.modifiedDate 
WHERE itemRank = 1 
ORDER BY modifiedDate DESC 

SELECT * FROM @destTable 
3

Merci pour toutes les réponses. J'ai une idée différente qui est beaucoup plus rapide que le curseur à l'ancienne mode et je pense que cela correspond à ce que je cherchais, donc je le partage ici aussi.

--Test Data 
DECLARE @sourceTable TABLE(number int,amount int, yr int, modifiedDate datetime, city nvarchar(100)) 
DECLARE @destTable TABLE(number int,amount int, yr int, modifiedDate datetime, city nvarchar(100)) 

INSERT INTO @sourceTable (number, amount, yr, modifiedDate, city) VALUES (1,100,2011,'01 Jan 2011', 'aaa') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, city) VALUES (1,100,2011,'02 Jan 2011', 'bbb') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, city) VALUES (2,4560,2011,'02 Jan 2011', 'ccc') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, city) VALUES (33,456,2010,'02 Jan 2011', 'ddd') 
INSERT INTO @sourceTable (number, amount, yr, modifiedDate, city) VALUES (22,456,2010,'02 Jan 2011', 'ddd') 

--Query 
INSERT INTO @destTable 
SELECT * FROM @sourceTable 
WHERE CAST(number AS NVARCHAR(100)) + '_' + CAST(amount AS NVARCHAR(100)) + '_' + CAST(yr AS NVARCHAR(100)) + '_' + CONVERT(NVARCHAR(100), modifiedDate,121) 
IN 
(
SELECT CAST(number AS NVARCHAR(100)) + '_' + CAST(amount AS NVARCHAR(100)) + '_' + CAST(yr AS NVARCHAR(100)) + '_' + CONVERT(NVARCHAR(100), MAX(modifiedDate),121) 
FROM @sourceTable 
GROUP BY number, amount, yr 
) 
--Results 
SELECT * FROM @destTable 
Questions connexes