Étant donné:
Deux requêtes qui nécessitent un filtrage:
select top 2 t1.ID, t1.ReceivedDate
from Table t1
where t1.Type = 'TYPE_1'
order by t1.ReceivedDate desc
Et:
select top 2 t2.ID
from Table t2
where t2.Type = 'TYPE_2'
order by t2.ReceivedDate desc
Séparément, ceux-ci renvoient les ID
s que je recherche: (13, 11 et 12, 6)
Fondamentalement, je veux les deux enregistrements les plus récents pour deux types de données spécifiques.
Je veux réunir ces deux requêtes comme suit:
select top 2 t1.ID, t2.ReceivedDate
from Table t1
where t1.Type = 'TYPE_1'
order by ReceivedDate desc
union
select top 2 t2.ID
from Table t2
where t2.Type = 'TYPE_2'
order by ReceivedDate desc
Problème:
Le problème est que cette requête n'est pas valide car le premier select
ne peut pas avoir un order by
clause si elle est unioned
. Et il ne peut pas avoir top 2
sans avoir order by
.
Comment puis-je résoudre cette situation?
Vous devriez pouvoir les alias et les utiliser comme sous-requêtes (une partie de la raison pour laquelle votre premier effort n'était pas valide était parce que la première sélection avait deux colonnes (ID et ReceivedDate) mais votre seconde n'en avait qu'une (ID) - aussi, Type est un réservé Word dans SQL Server, et ne peut pas être utilisé comme vous l'aviez comme nom de colonne):
declare @Tbl1 table(ID int, ReceivedDate datetime, ItemType Varchar(10))
declare @Tbl2 table(ID int, ReceivedDate datetime, ItemType Varchar(10))
insert into @Tbl1 values(1, '20010101', 'Type_1')
insert into @Tbl1 values(2, '20010102', 'Type_1')
insert into @Tbl1 values(3, '20010103', 'Type_3')
insert into @Tbl2 values(10, '20010101', 'Type_2')
insert into @Tbl2 values(20, '20010102', 'Type_3')
insert into @Tbl2 values(30, '20010103', 'Type_2')
SELECT a.ID, a.ReceivedDate FROM
(select top 2 t1.ID, t1.ReceivedDate
from @tbl1 t1
where t1.ItemType = 'TYPE_1'
order by ReceivedDate desc
) a
union
SELECT b.ID, b.ReceivedDate FROM
(select top 2 t2.ID, t2.ReceivedDate
from @tbl2 t2
where t2.ItemType = 'TYPE_2'
order by t2.ReceivedDate desc
) b
select * from
(
select top 2 t1.ID, t1.ReceivedDate
from Table t1
where t1.Type = 'TYPE_1'
order by t1.ReceivedDate de
) t1
union
select * from
(
select top 2 t2.ID
from Table t2
where t2.Type = 'TYPE_2'
order by t2.ReceivedDate desc
) t2
ou en utilisant CTE (SQL Server 2005+)
;with One as
(
select top 2 t1.ID, t1.ReceivedDate
from Table t1
where t1.Type = 'TYPE_1'
order by t1.ReceivedDate de
)
,Two as
(
select top 2 t2.ID
from Table t2
where t2.Type = 'TYPE_2'
order by t2.ReceivedDate desc
)
select * from One
union
select * from Two
declare @T1 table(ID int, ReceivedDate datetime, [type] varchar(10))
declare @T2 table(ID int, ReceivedDate datetime, [type] varchar(10))
insert into @T1 values(1, '20010101', '1')
insert into @T1 values(2, '20010102', '1')
insert into @T1 values(3, '20010103', '1')
insert into @T2 values(10, '20010101', '2')
insert into @T2 values(20, '20010102', '2')
insert into @T2 values(30, '20010103', '2')
;with cte1 as
(
select *,
row_number() over(order by ReceivedDate desc) as rn
from @T1
where [type] = '1'
),
cte2 as
(
select *,
row_number() over(order by ReceivedDate desc) as rn
from @T2
where [type] = '2'
)
select *
from cte1
where rn <= 2
union all
select *
from cte2
where rn <= 2
La prémisse de base de la question et des réponses est fausse. Chaque Select dans une union peut avoir une clause where. C'est l'ORDRE PAR dans la première requête qui vous donne l'erreur.
La réponse est trompeuse car elle tente de résoudre un problème qui n'est pas un problème. Vous POUVEZ en fait avoir une CLAUSE OERE dans chaque segment d'une UNION. Vous ne pouvez pas avoir un ORDER BY sauf dans le dernier segment. Par conséquent, cela devrait fonctionner ...
select top 2 t1.ID, t1.ReceivedDate
from Table t1
where t1.Type = 'TYPE_1'
-----remove this-- order by ReceivedDate desc
union
select top 2 t2.ID, t2.ReceivedDate --- add second column
from Table t2
where t2.Type = 'TYPE_2'
order by ReceivedDate desc
Créez des vues sur les deux premiers "selects" et "union".
Notez que chaque instruction SELECT dans l'UNION doit avoir le même nombre de colonnes. Les colonnes doivent également avoir des types de données similaires. En outre, les colonnes de chaque instruction SELECT doivent être dans le même ordre. vous choisissez
t1.ID, t2.ReceivedDate du tableau t1
syndicat
t2.ID du tableau t2
ce qui est incorrect.
il faut donc écrire
t1.ID, t1.ReceivedDate du tableau t1 union t2.ID, t2.ReceivedDate du tableau t1
vous pouvez utiliser la sous-requête ici
SELECT tbl1.ID, tbl1.ReceivedDate FROM
(select top 2 t1.ID, t1.ReceivedDate
from tbl1 t1
where t1.ItemType = 'TYPE_1'
order by ReceivedDate desc
) tbl1
union
SELECT tbl2.ID, tbl2.ReceivedDate FROM
(select top 2 t2.ID, t2.ReceivedDate
from tbl2 t2
where t2.ItemType = 'TYPE_2'
order by t2.ReceivedDate desc
) tbl2
il ne renverra donc que des valeurs distinctes par défaut des deux tables.