2013-04-01 2 views
0

У меня есть SQL-запрос, где я пытаюсь получить различные значения после объединения двух запросов. Я уже использовал Distinct в обоих запросах.SQL Query Returning Повторяющиеся значения после использования UNION и Distinct

У меня есть RegID в качестве первичного ключа в таблице Registration и для каждой записи в таблице регистрации имеются соответствующие записи в RoomType т.е., RoomType таблицы имеет RegID как внешний ключ.

Теперь проблема в том, если у вас есть несколько записей в таблице RoomType для конкретного RegID Я получаю дубликат Regid's.

Моя печать запрос, как это:

SELECT DISTINCT 
    dbo.tbRegistration.RegID, 
    dbo.tbRegistration.PropertyName, dbo.tbRegistration.IsActive, 
    dbo.tbRegistration.Stars, dbo.tbRegistration.City, 
    dbo.tbRegistration.Address, 
    dbo.tbHotelImages.MainImage, dbo.tbHotelImages.Img1, 
    dbo.tbHotelImages.Img2, dbo.tbHotelImages.Img3, 
    dbo.tbHotelImages.Img4, dbo.tbHotelImages.Img5, 
    dbo.tbHotelImages.Img6, dbo.tbHotelImages.Img7, 
    dbo.tbHotelImages.Img8, dbo.tbHotelImages.Img9, 
    dbo.tbRegistration.PropertyID, 
    dbo.tbHotelFeatures.*, 
    dbo.tbBillingPlan.BaseRate, dbo.tbRoomType.Name as RoomTypeName 
FROM   
    dbo.tbRoomType 
LEFT OUTER JOIN 
    dbo.tbRegistration ON dbo.tbRoomType.RegID = dbo.tbRegistration.RegID 
LEFT OUTER JOIN 
    dbo.tbBillingPlan ON dbo.tbRoomType.RTID = dbo.tbBillingPlan.RTID  
LEFT OUTER JOIN 
    dbo.tbHotelFeatures ON dbo.tbRegistration.RegID = dbo.tbHotelFeatures.RegID 
LEFT OUTER JOIN 
    dbo.tbHotelImages ON dbo.tbRegistration.RegID = dbo.tbHotelImages.RegID           
WHERE 
    tbRegistration.PMS = 0 
    AND tbRegistration.Stars IN (0) OR 1=1 
    AND (tbRegistration.City LIKE '%' + @SearchText + '%') 
    AND (tbRoomType.Adults >= @Adults OR tbRoomType.Children >= @Children) 
    AND (dbo.GetFreeRoomType(dbo.tbRoomType.RTID, @CheckIn, @CheckOut) > 0) 
    AND dbo.tbRegistration.IsActive = 1  

UNION 

SELECT DISTINCT 
    dbo.tbRegistration.RegID , dbo.tbRegistration.PropertyName, dbo.tbRegistration.IsActive, dbo.tbRegistration.Stars, dbo.tbRegistration.City, dbo.tbRegistration.Address, 
         dbo.tbHotelImages.MainImage, dbo.tbHotelImages.Img1, dbo.tbHotelImages.Img2, dbo.tbHotelImages.Img3, dbo.tbHotelImages.Img4, dbo.tbHotelImages.Img5, 
         dbo.tbHotelImages.Img6, dbo.tbHotelImages.Img7, dbo.tbHotelImages.Img8, dbo.tbHotelImages.Img9, dbo.tbRegistration.PropertyID , 
         dbo.tbHotelFeatures.*, dbo.tbBillingPlan.BaseRate,dbo.tbRoomType.Name as RoomTypeName 
FROM   dbo.tbRoomType left OUTER JOIN 
         dbo.tbRegistration ON dbo.tbRoomType.RegID = dbo.tbRegistration.RegID left OUTER JOIN 
         dbo.tbBillingPlan ON dbo.tbRoomType.RTID = dbo.tbBillingPlan.RTID LEFT OUTER JOIN 
         dbo.tbHotelFeatures ON dbo.tbRegistration.RegID = dbo.tbHotelFeatures.RegID LEFT OUTER JOIN 
         dbo.tbHotelImages ON dbo.tbRegistration.RegID = dbo.tbHotelImages.RegID           
     Where tbRegistration.PMS=1 and tbRegistration.Stars IN ( 0) or 1=1 and (tbRegistration.City like '%' + @SearchText + '%')  

and (tbRoomType.Adults>[email protected] or tbRoomType.Children>[email protected]) 
and(dbTestSparrowPMS . dbo.GetFreeRoomType(dbo.tbRoomType.ID, @CheckIn, @CheckOut) >0) and dbo.tbRegistration.IsActive=1 



    order by tbRegistration.RegID 

и моя процедура выглядит так:

USE [dbTestSearchMyHotel] 
GO 
/****** Object: StoredProcedure [dbo].[prRegistrationSearchFreeHotels] Script Date: 04/01/2013 12:06:26 ******/ 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
-- ============================================= 
-- Author:  <Author,,Name> 
-- Create date: <Create Date,,> 
-- Description: <Description,,> 
-- ============================================= 
ALTER PROCEDURE [dbo].[prRegistrationSearchFreeHotels] -- 's','4/27/2013','4/28/2013',1,1,0,0,0,0,0,0,0 

    -- Add the parameters for the stored procedure here select * from tbRegistration where Stars in(1,4) 

@SearchText varchar(4000), 
@CheckIn date, 
@CheckOut date, 
@Adults int, 
@Children int, 
@Min float, 
@Max float, 
@OneStar bit, 
@TwoStar bit, 
@ThreeStar bit, 
@FourStar bit, 
@FiveStar bit 

    AS 
    Declare @SQLQuery AS NVarchar(4000) 
Declare @ParamDefinition AS NVarchar(4000) 
declare @n as bit 
set @n=0 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

    -- Insert statements for procedure here 

    Set @SQLQuery='SELECT DISTINCT 
         dbo.tbRegistration.RegID , dbo.tbRegistration.PropertyName,dbo.tbRegistration.IsActive, dbo.tbRegistration.Stars, dbo.tbRegistration.City, dbo.tbRegistration.Address, 
         dbo.tbHotelImages.MainImage, dbo.tbHotelImages.Img1, dbo.tbHotelImages.Img2, dbo.tbHotelImages.Img3, dbo.tbHotelImages.Img4, dbo.tbHotelImages.Img5, 
         dbo.tbHotelImages.Img6, dbo.tbHotelImages.Img7, dbo.tbHotelImages.Img8, dbo.tbHotelImages.Img9, dbo.tbRegistration.PropertyID , 
         dbo.tbHotelFeatures.*, dbo.tbBillingPlan.BaseRate,dbo.tbRoomType.Name as RoomTypeName 
FROM   dbo.tbRoomType left OUTER JOIN 
         dbo.tbRegistration ON dbo.tbRoomType.RegID = dbo.tbRegistration.RegID left OUTER JOIN 
         dbo.tbBillingPlan ON dbo.tbRoomType.RTID = dbo.tbBillingPlan.RTID LEFT OUTER JOIN 
         dbo.tbHotelFeatures ON dbo.tbRegistration.RegID = dbo.tbHotelFeatures.RegID LEFT OUTER JOIN 
         dbo.tbHotelImages ON dbo.tbRegistration.RegID = dbo.tbHotelImages.RegID           
           Where tbRegistration.PMS=0 and tbRegistration.Stars IN ( ' 
    if @OneStar =1 
    begin 
    set @n =1 
    set @SQLQuery [email protected] +' 1 ' 
    end 

    if @TwoStar =1 
    begin 
    if @n =1 
    begin 
    set @SQLQuery [email protected] +' , 2 ' 
     end 
    else 
    begin 
    set @n=1 
    set @SQLQuery [email protected] +' 2 ' 
     end 
end 

    if @ThreeStar =1 
    begin 
    if @n =1 
    begin 
    set @SQLQuery [email protected] +' , 3 ' 
    end 
    else 
    begin 
    set @n=1 
    set @SQLQuery [email protected] +' 3 ' 
    end 
end 

    if @FourStar =1 
    begin 
    if @n =1 
    begin 
    set @SQLQuery [email protected] +' , 4 ' 
    end 
    else 
    begin 
    set @n=1 
     set @SQLQuery [email protected] +' 4 ' 
    end 
    end 

    if @FiveStar =1 
    begin 
    if @n =1 
    begin 
    set @SQLQuery [email protected] +' , 5 ' 
    end 
    else 
    begin 
    set @n=1 
    set @SQLQuery [email protected] +' 5 ' 
    end 
    end       
    if @n=0 
begin 
    set @SQLQuery [email protected] +' 0) or 1=1 and ' 
end  
else 
begin      
set @SQLQuery [email protected] +') and ' 
end 
set @SQLQuery [email protected] +' (tbRegistration.City like ''%'' + @SearchText + ''%'') 

and (tbRoomType.Adults>[email protected] or tbRoomType.Children>[email protected]) 
and(dbo.GetFreeRoomType(dbo.tbRoomType.RTID, @CheckIn, @CheckOut) >0) and dbo.tbRegistration.IsActive=1 ' 
if @Min > 0 and @Max > 0 
set @SQLQuery [email protected] +' and (tbBillingPlan.BaseRate>[email protected]) and (tbBillingPlan.BaseRate<[email protected]) ' 





    set @SQLQuery [email protected] +' union ' 
    set @n=0 
Set @[email protected]+'SELECT DISTINCT 
         dbo.tbRegistration.RegID , dbo.tbRegistration.PropertyName, dbo.tbRegistration.IsActive, dbo.tbRegistration.Stars, dbo.tbRegistration.City, dbo.tbRegistration.Address, 
         dbo.tbHotelImages.MainImage, dbo.tbHotelImages.Img1, dbo.tbHotelImages.Img2, dbo.tbHotelImages.Img3, dbo.tbHotelImages.Img4, dbo.tbHotelImages.Img5, 
         dbo.tbHotelImages.Img6, dbo.tbHotelImages.Img7, dbo.tbHotelImages.Img8, dbo.tbHotelImages.Img9, dbo.tbRegistration.PropertyID , 
         dbo.tbHotelFeatures.*, dbo.tbBillingPlan.BaseRate,dbo.tbRoomType.Name as RoomTypeName 
FROM   dbo.tbRoomType left OUTER JOIN 
         dbo.tbRegistration ON dbo.tbRoomType.RegID = dbo.tbRegistration.RegID left OUTER JOIN 
         dbo.tbBillingPlan ON dbo.tbRoomType.RTID = dbo.tbBillingPlan.RTID LEFT OUTER JOIN 
         dbo.tbHotelFeatures ON dbo.tbRegistration.RegID = dbo.tbHotelFeatures.RegID LEFT OUTER JOIN 
         dbo.tbHotelImages ON dbo.tbRegistration.RegID = dbo.tbHotelImages.RegID           
     Where tbRegistration.PMS=1 and tbRegistration.Stars IN ( ' 
    if @OneStar =1 
    begin 
    set @n =1 
set @SQLQuery [email protected] +' 1 ' 
end 
    if @TwoStar =1 
    begin 
     if @n =1 
     begin 
     set @SQLQuery [email protected] +', 2 ' 
     end 
     else 
     begin 
     set @SQLQuery [email protected] +' 2 ' 
     set @n=1 
      end 
    end 
    if @ThreeStar =1 
    begin 
     if @n =1 
      begin 
     set @SQLQuery [email protected] +' , 3 ' 
     end 
     else 
     begin 
     set @n=1 
     set @SQLQuery [email protected] +' 3' 
      end 
end 

    if @FourStar =1 
    begin 
     if @n =1 
     begin 
     set @SQLQuery [email protected] +' , 4 ' 
     end 
     else 
     begin 
     Set @n=1 
     set @SQLQuery [email protected] +' 4 ' 
     end 
end 
    if @FiveStar =1 
    begin 
     if @n =1 
     begin 
     set @SQLQuery [email protected] +', 5 ' 
     end 
     else 
     begin 
     Set @n=1 
     set @SQLQuery [email protected] +' 5 ' 
     end 
end       
    if @n=0 
begin 
    set @SQLQuery [email protected] +' 0) or 1=1 and ' 
end  
else 
begin      
set @SQLQuery [email protected] +') and ' 
end 
set @SQLQuery [email protected] +' (tbRegistration.City like ''%'' + @SearchText + ''%'')  

and (tbRoomType.Adults>[email protected] or tbRoomType.Children>[email protected]) 
and(dbTestSparrowPMS . dbo.GetFreeRoomType(dbo.tbRoomType.ID, @CheckIn, @CheckOut) >0) and dbo.tbRegistration.IsActive=1 



    ' 

if @Min > 0 and @Max > 0 
set @SQLQuery [email protected] +' and (tbBillingPlan.BaseRate>[email protected]) and (tbBillingPlan.BaseRate<[email protected]) ' 



set @[email protected] + ' order by tbRegistration.RegID' 
    -- 

     Set @ParamDefinition = ' 
@SearchText varchar(4000), 
@CheckIn date, 
@CheckOut date, 
@Adults int, 
@Children int, 
@Min float, 
@Max float, 
@OneStar bit, 
@TwoStar bit, 
@ThreeStar bit, 
@FourStar bit, 
@FiveStar bit' 
    --print @SQLQuery   
    /* Execute the Transact-SQL String with all parameter value's 
     Using sp_executesql Command */ 
    Execute sp_Executesql  @SQLQuery, 
       @ParamDefinition, 

       @SearchText , 
       @CheckIn , 
       @CheckOut , 
       @Adults , 
       @Children , 
       @Min, 
       @Max, 
       @OneStar , 
       @TwoStar , 
       @ThreeStar , 
       @FourStar , 
       @FiveStar 



    return 



    end 

ответ

0

UNION удаляет повторяющиеся записи (UNION = SELECT DISTINCT), в то время как UNION ALL возвращает повторяющиеся записи. Пожалуйста, проверьте связь this.

Теперь в вашем запросе вы выполняете SELECT DISTINCT на обоих запросах и используете UNION с ними. Но если ваш оба запроса возвращают разное значение для одного из столбцов, вы получите оба из них, и UNION не удалит дубликат.

Для например

ID Текст

1 B

Таким образом, вы должны либо удалить этот столбец, имеющий различное значение и, следовательно, возвращая повторяющиеся записи для вас, если это возможно. ИЛИ добавить условие, которое отфильтровывает записи, уже выбранные в первом запросе.

+0

Nil thx, но я добавил условие (где PMS = 0 или PMS = 1 в запросе см. Мою процедуру или Query Print), но он возвращает повторяющиеся строки даже тогда. –

+0

Также оба запроса имеют одинаковые строки, только условия, проверенные в 2 запросах, различны. –

+0

Если у вас вообще не должно быть разницы, вы не должны иметь такой же результат. Надеюсь, ты получишь мою мысль! –