Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 SQL 2000. SELECT возвращает неверное количество записей.  [new]
step_ks
Member

Откуда:
Сообщений: 936
Пока еще многие работают на 2000 сервере, решил отписаться.
Может помочь избежать сюрпризов.

На

Microsoft SQL Server  2000 - 8.00.2055 (Intel X86)   Dec 16 2008 19:46:53   Copyright (c) 1988-2003 Microsoft Corporation  Developer Edition on Windows NT 5.2 (Build 3790: Service Pack 2) 

запрос вида

declare @t1 table (fld1 int, id int identity (1,1))
insert @t1 default values
insert @t1 default values

declare @t2 table (fld2 int)

select  
    t1.fld1,
    fld3  =  ( 
               select max(a.fld1)
                 from(
                        select t1.fld1 from @t2 t2
                      ) a
             ) 
    from @t1 t1
    where t1.id=1
    group by t1.fld1
    

возвращает неверное количество записей. В данном случае 2 вместо 1. Обходные пути есть (например, завернуть весь запрос в derived table и вынести group by наружу). Но сам факт может попортить нервов. На 2005 и 2008 уже всё работает правильно.
12 май 11, 11:24    [10640190]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
2000 под рукой нет, но чет ну очнеь слабо вериться если честно , что
where t1.id=1
вернет 2 записи из таблицы вида
NULL 1
NULL 2
12 май 11, 12:16    [10640625]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
step_ks
Member

Откуда:
Сообщений: 936
Добавил в запрос id:
declare @t1 table (fld1 int, id int identity (1,1))
insert @t1 default values
insert @t1 default values

declare @t2 table (fld2 int)

select  
    t1.fld1,
    t1.id,
    fld3  =  ( 
               select max(a.fld1)
                 from(
                        select t1.fld1 from @t2 t2
                      ) a
             ) 
    from @t1 t1
    where t1.id=1
    group by t1.fld1, t1.id

Результат:
fld1        id          fld3
----------- ----------- -----------
NULL 1 NULL
NULL 2 NULL

Вот так.
12 май 11, 12:20    [10640656]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
Glory
Member

Откуда:
Сообщений: 104751
а подзапрос select t1.fld1 from @t2 t2 какую цель преследует ?
12 май 11, 12:20    [10640659]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
step_ks
Member

Откуда:
Сообщений: 936
Glory
а подзапрос select t1.fld1 from @t2 t2 какую цель преследует ?

В приведенном вырожденном примере можно сказать, что никакую. Он лишь демонстрирует вид конструкции, которая приводит к проблеме.
Конечно, в исходном рабочем коде подзапрос был другой, сложнее, с where и несколькмим вычисленными полями в селект-листе.
12 май 11, 12:27    [10640710]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
Glory
Member

Откуда:
Сообщений: 104751
step_ks
Glory
а подзапрос select t1.fld1 from @t2 t2 какую цель преследует ?

В приведенном вырожденном примере можно сказать, что никакую. Он лишь демонстрирует вид конструкции, которая приводит к проблеме.
Конечно, в исходном рабочем коде подзапрос был другой, сложнее, с where и несколькмим вычисленными полями в селект-листе.

И этот сложный подзапрос тоже возвращает поле _внешней_ таблицы ? И это делается осознано ?
12 май 11, 12:29    [10640726]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
То есть
WHERE t1.id=1
пропустил
t1.id=2
??
Может, что-то поломалось в базе?
Индексы накрылись?

Иначе этого просто не может быть.
12 май 11, 12:31    [10640750]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
гм,
Guest
iap
То есть
WHERE t1.id=1
пропустил
t1.id=2
??
Может, что-то поломалось в базе?
Индексы накрылись?

Иначе этого просто не может быть.

Microsoft SQL Server  2000 - 8.00.194 (Intel X86) 
	Aug  6 2000 00:57:48 
	Copyright (c) 1988-2000 Microsoft Corporation
	Desktop Engine on Windows NT 5.1 (Build 2600: Service Pack 2)


К сообщению приложен файл. Размер - 39Kb
12 май 11, 12:35    [10640777]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
гм,
Guest
declare @t1 table (fld1 int, id int identity (1,1))
insert @t1 default values
insert @t1 default values

declare @t2 table (fld2 int)

select  
    t1.fld1,
    t1.id,
    fld3  = ( 
               select max(a.fld1)
                 from(
                        select t1.fld1 from @t2 t2
                      ) a
             ) 
    from @t1 t1
    where t1.id=1
/*    group by t1.fld1, t1.id */

fld1        id          fld3        
----------- ----------- ----------- 
NULL        1           NULL
12 май 11, 12:43    [10640852]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
step_ks
Member

Откуда:
Сообщений: 936
Glory
step_ks
пропущено...

В приведенном вырожденном примере можно сказать, что никакую. Он лишь демонстрирует вид конструкции, которая приводит к проблеме.
Конечно, в исходном рабочем коде подзапрос был другой, сложнее, с where и несколькмим вычисленными полями в селект-листе.

И этот сложный подзапрос тоже возвращает поле _внешней_ таблицы ? И это делается осознано ?

Не возвращает. Использует в вычислении. но эффект тот же.
Было примерно такое:
......
fld3 =
  
(
 select coalesce (  
                    case when count(distinct a.r1)=1 then max(a.r1) end,
                    case when count(distinct a.r2)=1 then max(a.r2) end
                   ......
                 )  
        from(
                select r1=case when t2.fld2=t1.fld1 then t2.fld2 end,
                       r2=case when t2.fld2=t1.fld2 then t2.fld2 end,
                       ....
                       from @t2 t2
                       where ....
              ) a
)              
........
12 май 11, 12:44    [10640854]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
Glory
Member

Откуда:
Сообщений: 104751
Не вижу "такого же эффекта"

select  
    t1.fld1,
    fld3  =  ( 
               select max(a.fld2)
                 from(
                        select t2.fld2 from @t2 t2
                      ) a
             )
    from @t1 t1
    where t1.id=1
    group by t1.fld1
12 май 11, 12:46    [10640877]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
Glamorama
Member

Откуда:
Сообщений: 152
Покажите план запроса для двух случаев - с MAX и TOP (1).
Такая проблема имеет место быть в win2003 r2+2005 SP2 ( установка SP3 проблему правит).
12 май 11, 12:48    [10640886]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
step_ks
Member

Откуда:
Сообщений: 936
Glory
Не вижу "такого же эффекта"


Надо, чтобы поле из внешней таблицы поучаствовало в выражениях селект-листа каким-нибудь образом:

select  
    t1.fld1,
    fld3  =  ( 
               select max(a.fld2)
                 from(
                        select fld2=t2.fld2+t1.fld1 from @t2 t2
                      ) a
             )
    from @t1 t1
    where t1.id=1
    group by t1.fld1
12 май 11, 12:51    [10640914]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
iljy
Member

Откуда:
Сообщений: 8711
iap
То есть
WHERE t1.id=1
пропустил
t1.id=2
??
Может, что-то поломалось в базе?
Индексы накрылись?

Иначе этого просто не может быть.

Может Только что проверил. Проблема с группировкой, убираешь ее - все хорошо.
12 май 11, 12:56    [10640950]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
step_ks
Member

Откуда:
Сообщений: 936
Glamorama
Покажите план запроса для двух случаев - с MAX и TOP (1).
Такая проблема имеет место быть в win2003 r2+2005 SP2 ( установка SP3 проблему правит).


C max (select max(a.fld1)... ) :

Rows Executes
------------------------------------------------------------------------------------------
2 1 |--Compute Scalar(DEFINE:([Expr1003]=[Expr1003]))
2 1 |--Nested Loops(Inner Join)
2 1 |--Nested Loops(Inner Join, OUTER REFERENCES:([t1].[fld1]))
2 1 | |--Table Scan(OBJECT:(@t1 AS [t1]))
2 2 | |--Hash Match(Cache, HASH:([t1].[fld1]), RESIDUAL:([t1].[fld1]=[t1].[fld1]))
1 1 | |--Stream Aggregate(DEFINE:([Expr1003]=MAX([t1].[fld1])))
0 1 | |--Table Scan(OBJECT:(@t2 AS [t2]))
2 2 |--Row Count Spool
1 1 |--Sort(DISTINCT ORDER BY:([t1].[fld1] ASC))
1 1 |--Table Scan(OBJECT:(@t1 AS [t1]), WHERE:([t1].[id]=1))


С top 1 (select top 1 a.fld1 ... ):

Rows Executes
------------------------------------------------------------------------------------------
2 1 |--Compute Scalar(DEFINE:([t1].[fld1]=[t1].[fld1]))
2 1 |--Nested Loops(Inner Join)
2 1 |--Nested Loops(Left Outer Join, OUTER REFERENCES:([t1].[fld1]))
2 1 | |--Table Scan(OBJECT:(@t1 AS [t1]))
0 2 | |--Hash Match(Cache, HASH:([t1].[fld1]), RESIDUAL:([t1].[fld1]=[t1].[fld1]))
0 2 | |--Top(1)
0 2 | |--Compute Scalar(DEFINE:([t1].[fld1]=[t1].[fld1]))
0 2 | |--Table Scan(OBJECT:(@t2 AS [t2]))
2 2 |--Row Count Spool
1 1 |--Sort(DISTINCT ORDER BY:([t1].[fld1] ASC))
1 1 |--Table Scan(OBJECT:(@t1 AS [t1]), WHERE:([t1].[id]=1))
12 май 11, 12:59    [10640964]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
WarAnt
Member

Откуда: Питер
Сообщений: 2423
step_ks,

Видимо до такого ацкого извращения моск программеров 2000 sql не смог додуматься, не ту траву курили или не столько много:)
12 май 11, 15:10    [10642090]     Ответить | Цитировать Сообщить модератору
 Re: SQL 2000. SELECT возвращает неверное количество записей.  [new]
Любитель покурить (из МС)
Guest
WarAnt
Видимо до такого ацкого извращения моск программеров 2000 sql не смог додуматься, не ту траву курили или не столько много:)
Так оно и было. Нам только к релизу Yukon'a траву нормальную подвезли.
12 май 11, 15:45    [10642443]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить