Select Distinct with text field problem in SQL Server

User avatar
AnyaGal
Уже с Приветом
Posts: 5771
Joined: 02 Dec 1999 10:01
Location: Saint-Petersburg --> Bellevue, WA

Select Distinct with text field problem in SQL Server

Post by AnyaGal »

Наткнулось на проблему - у меня довольно сложный запрос по 4-м таблицам, одна из которых linking table с кучей where clause.

Короче нужно мне использовать SELECT DISTINCT, а одно из запрашиваемых полей имеет datatype text.
SQL Server выдает ошибку Error 8163

The text, ntext or image data type cannot be selected as DISTINCT.

Action - Remove references to any text, ntext, or image columns when using SELECT DISTINCT.


Чего делать? Сразу оговорюсь, что stored procedures использовать нельзя.

Хотела создать View с нужными SELECT Distinct чтобы получить набор IDs i потом его использовать в SQL statement, но view этот нельзя построит без параметра, который будет известен только в run time.
То есть колонка из-за кототой DISTINCT нужен отображаться не должна, но по ней должен быть дынамический Where clause.

Чего-то я слегка зашла в тупик. Сейчас постараюсь пример привести...
User avatar
KVA
Уже с Приветом
Posts: 5347
Joined: 03 Feb 1999 10:01
Location: NJ, USA

Post by KVA »

You will not be able to do distinct on Text datatype. But you use varchar(255) instead. Or you can convert text to varchar using convert function and issue distinct on that. Drawback is you will get the data truncted at 255 chars.
SBolgov
Уже с Приветом
Posts: 14006
Joined: 17 Jun 2003 04:41

Re: Select Distinct with text field problem in SQL Server

Post by SBolgov »

AnyaGal wrote:Хотела создать View с нужными SELECT Distinct чтобы получить набор IDs i потом его использовать в SQL statement, но view этот нельзя построит без параметра, который будет известен только в run time.
То есть колонка из-за кототой DISTINCT нужен отображаться не должна, но по ней должен быть дынамический Where clause.

Чего-то я слегка зашла в тупик. Сейчас постараюсь пример привести...

Есть подозрение, что то, что Вы хотите, можно сделать проще. Приведите пример - разберёмся. ;)
Не гоните, и не гонимы будете...
User avatar
AnyaGal
Уже с Приветом
Posts: 5771
Joined: 02 Dec 1999 10:01
Location: Saint-Petersburg --> Bellevue, WA

Post by AnyaGal »

Table1
field: ID1(int)
field:Desription (text)

данные
ID1 Description
1..........."Text1"
2..........."Text2"
3..........."Text3"

Table2
field: ID2 (int)

Данные:

ID2
1
2
3


Table3 (Linkin table for table1 i Table2)
field: ID1
field ID2

Data
ID1 ID2
1............1
1............2
1............3
2............2
3............3

Конечный запрос должен быть:
Select DISTINCT Table1.ID1, Table1.Description FROM Table1 INNER JOIN Table3 ON Table1.ID1=Table3.ID1 Where table3.ID2 IN (1,2)

То есть в результате "Text1" и "Text2" должны встречаться только по разу.
То есть пример - например один продукт относится к многим категориям и вам надо найти список продуктов входящий в заданный набор категорий но без дупликатов
Description from table1 is a text field (with datatype=text)
Значения внутри IN известны в run time.
Last edited by AnyaGal on 22 Jul 2004 00:57, edited 1 time in total.
User avatar
AnyaGal
Уже с Приветом
Posts: 5771
Joined: 02 Dec 1999 10:01
Location: Saint-Petersburg --> Bellevue, WA

Post by AnyaGal »

varchar использовать не могу - это поле используется для введения длинного текста.
SBolgov
Уже с Приветом
Posts: 14006
Joined: 17 Jun 2003 04:41

Post by SBolgov »

Code: Select all

SELECT
  ID1,
  Description
FROM
  Table1
WHERE
  ID1 IN (Select ID1 FROM Table3 WHERE ID2 IN (1,2))
Не гоните, и не гонимы будете...
User avatar
AnyaGal
Уже с Приветом
Posts: 5771
Joined: 02 Dec 1999 10:01
Location: Saint-Petersburg --> Bellevue, WA

Post by AnyaGal »

SBolgov wrote:

Code: Select all

SELECT
  ID1,
  Description
FROM
  Table1
WHERE
  ID1 IN (Select ID1 FROM Table3 WHERE ID2 IN (1,2))


Чего-то похожее я пыталссь седлать, но у меня там еще две-три таблицы со связями и куча полей, и чего-то там не так изображалось, может я просто запуталсь, завтра еще раз на ваш способ гляну
SBolgov
Уже с Приветом
Posts: 14006
Joined: 17 Jun 2003 04:41

Post by SBolgov »

Я вот не помню - SQL Server позволяет во FROM подзапросы использовать ?

Если позволяет, то можно так:

Code: Select all

SELECT
  Table1.ID1,
  Table1.Description
FROM
  Table1
  INNER JOIN (Select DISTINCT ID1 FROM Table3 WHERE ID2 IN (1,2)) ON Table1.ID1 = ID1


За абсолютную точность синтаксиса не ручаюсь, SQL Server под рукой нет, проверить не могу. :(
Last edited by SBolgov on 22 Jul 2004 01:46, edited 1 time in total.
Не гоните, и не гонимы будете...
User avatar
Sabina
Уже с Приветом
Posts: 5669
Joined: 13 Oct 2000 09:01
Location: East Bay, CA

Post by Sabina »

SBolgov wrote:

Code: Select all

SELECT DISTINCT
  Table1.ID1,
  Table1.Description
FROM
  Table1
  INNER JOIN (Select DISTINCT ID1 FROM Table3 WHERE ID2 IN (1,2)) ON Table1.ID1 = ID1



Так тут тот же SELECT DISTINCT для текст поля Table1.Description ..
Или я чего-то недопонимаю?
Last edited by Sabina on 22 Jul 2004 03:09, edited 1 time in total.
User avatar
Sabina
Уже с Приветом
Posts: 5669
Joined: 13 Oct 2000 09:01
Location: East Bay, CA

Post by Sabina »

AnyaGal wrote:Table2
field: ID2 (int)

Данные:

ID2
1
2
3


Аня, а что в таблице 2 одни ID или ты просто не стала расписывать?
Last edited by Sabina on 22 Jul 2004 03:08, edited 1 time in total.
SBolgov
Уже с Приветом
Posts: 14006
Joined: 17 Jun 2003 04:41

Post by SBolgov »

Sabina wrote:Так тут тот же SELECT DISTINCT для текст поля Table1.Description ..
Или я чего-то недопонимаю?

Пардон, опечатка. :oops: Уже исправил.

Разумеется, DISTINCT должен быть только во внутреннем SELECT, а не во внешнем.

Сабина, спасибо! ;)
Не гоните, и не гонимы будете...
User avatar
AnyaGal
Уже с Приветом
Posts: 5771
Joined: 02 Dec 1999 10:01
Location: Saint-Petersburg --> Bellevue, WA

Post by AnyaGal »

Спасибо, завтра попробую.

Sabina wrote:Аня, а что в таблице 2 одни ID или ты просто не стала расписывать?

Сабина


Еще чего-то есть :) и вообще там много чего еще есть из других таблиц, я просто все для примера упростила.
User avatar
Sabina
Уже с Приветом
Posts: 5669
Joined: 13 Oct 2000 09:01
Location: East Bay, CA

Post by Sabina »

AnyaGal wrote:Еще чего-то есть :) и вообще там много чего еще есть из других таблиц, я просто все для примера упростила.


А я вот что-то сделалась confused от такого упрощения :wink:
Last edited by Sabina on 22 Jul 2004 03:08, edited 1 time in total.
User avatar
AnyaGal
Уже с Приветом
Posts: 5771
Joined: 02 Dec 1999 10:01
Location: Saint-Petersburg --> Bellevue, WA

Post by AnyaGal »

Другие поля из второй таблицы используются в других запросах, я ее привела только для того стобы показать, что таблица №3 - связующая many-to-many
User avatar
Vik_NJ
Уже с Приветом
Posts: 1995
Joined: 29 Dec 2001 10:01
Location: Kiev->...->NYC

Post by Vik_NJ »

Скорее всего работать не будет, но может попробовать добавить к Вашему selectу
union
SELECT ID1, Description from table1 where 1=2
( union тоже дублирующие записи должен убирать ) :D
I may grow old, but I refuse to grow up!
User avatar
Sabina
Уже с Приветом
Posts: 5669
Joined: 13 Oct 2000 09:01
Location: East Bay, CA

Post by Sabina »

Vik_NJ wrote:Скорее всего работать не будет, но может попробовать добавить к Вашему selectу
union
SELECT ID1, Description from table1 where 1=2
( union тоже дублирующие записи должен убирать ) :D


UNION может дать ту же ошибку
http://www.experts-exchange.com/Databases/Microsoft_SQL_Server/Q_20829157.html

Q:
SELECT * FROM vw_performance_evenement_1
UNION
SELECT * FROM vw_performance_evenement_2

gives this error:
"The text, ntext, or image data type cannot be selected as DISTINCT."
But each of the separate queries don't give any problem.
There isn't any use of "DISTINCT" in the views used.

A:
A little bit of explaination now :

select 1 union select 2

is the same than

select distinct * from (select1 union all select2)

Note :
union and union all are not equivalent

if the two querie's results are not logically exclusive (ie if their intersection is not null), you migth get duplicate records
Sergey___K
Уже с Приветом
Posts: 13014
Joined: 10 Jul 2001 09:01
Location: VA

Post by Sergey___K »

Сделайте GROUP BY по тому, что DISTINCT и JOIN это по тому же самому "в туда", где TEXT.
User avatar
Strannik223
Уже с Приветом
Posts: 569
Joined: 14 Dec 2003 04:06
Location: Львов->Киев->Торонто

Post by Strannik223 »

Вообще то принято в вопросах по сиквелу полные DDL приводить. Я например не могу понять что в приведеной задаче нужно DISTINCT-ить. Desription?
Никакой разрухи нет. (с) Проф. Преображенский.
User avatar
AnyaGal
Уже с Приветом
Posts: 5771
Joined: 02 Dec 1999 10:01
Location: Saint-Petersburg --> Bellevue, WA

Post by AnyaGal »

Distinct надо по Table1.ID1, но к нему нужно много других полей прицепить из табле1, в том числе и Description.

Я всмотрелась в свою же первую вчерашнюю попытку, которая не работала (аналог того, что SBolgov предложил с самого начала - со вторым IN), нашла там ошибку, исправила, вроде работает.


С Group By попробовала сегодня, но с налету не получилось, не нравится какое-то поле, может я там тоже ошиблась в чем-то или не так поняла.

Ладно буду дальше тестировать. :)
Спасибо
User avatar
AnyaGal
Уже с Приветом
Posts: 5771
Joined: 02 Dec 1999 10:01
Location: Saint-Petersburg --> Bellevue, WA

Post by AnyaGal »

То бишь сейчас что-то типа:

Code: Select all

SELECT ID1, ID2 
FROM Table1
WHERE ID1 IN
(SELECT DISTINCT Table1.ID1
FROM Table1 INNER JOIN Table3
ON Table1.ID1=Table3.ID1
WHERE Table3.ID2 IN (1,2))
User avatar
Strannik223
Уже с Приветом
Posts: 569
Joined: 14 Dec 2003 04:06
Location: Львов->Киев->Торонто

Post by Strannik223 »

Code: Select all

select
  (select top 1 Description from Table1 where ID=t1.ID) as Description
from (select distinct ID from Table1) t1
join....
join....
join....


Не уверен что можно это сделать с group by, потому что ни одна функция агрегации не сработает по текстовому полю.
Никакой разрухи нет. (с) Проф. Преображенский.
User avatar
AnyaGal
Уже с Приветом
Posts: 5771
Joined: 02 Dec 1999 10:01
Location: Saint-Petersburg --> Bellevue, WA

Post by AnyaGal »

SBolgov wrote:

Code: Select all

SELECT
  ID1,
  Description
FROM
  Table1
WHERE
  ID1 IN (Select ID1 FROM Table3 WHERE ID2 IN (1,2))


Во это наверное лучше, только во второй select Distinct хорошо бы добавить. :roll:

А в моем варианте кажись Inner Join в IN лишняя, но вроде как работает. :roll:
User avatar
Strannik223
Уже с Приветом
Posts: 569
Joined: 14 Dec 2003 04:06
Location: Львов->Киев->Торонто

Post by Strannik223 »

AnyaGal wrote:То бишь сейчас что-то типа:

Code: Select all

SELECT ID1, ID2 
FROM Table1
WHERE ID1 IN
(SELECT DISTINCT Table1.ID1
FROM Table1 INNER JOIN Table3
ON Table1.ID1=Table3.ID1
WHERE Table3.ID2 IN (1,2))


1. ID2 к какой таблице относится??? Рекомендую всегда использовать aliases.
2. Если подзапрос вернет ID={1}, то при "WHERE ID1 IN" получишь 2 записи, у которых ID=1, разве нет? И какой же это distinct?
Никакой разрухи нет. (с) Проф. Преображенский.
User avatar
AnyaGal
Уже с Приветом
Posts: 5771
Joined: 02 Dec 1999 10:01
Location: Saint-Petersburg --> Bellevue, WA

Post by AnyaGal »

Code: Select all

SELECT 
  ID1,
  Description
FROM
  Table1
WHERE
  ID1 IN (Select Distinct ID1 FROM Table3 WHERE ID2 IN (1,2))


Во так тоже работает и это по-моему пока самое простое решение :)
User avatar
Strannik223
Уже с Приветом
Posts: 569
Joined: 14 Dec 2003 04:06
Location: Львов->Киев->Торонто

Post by Strannik223 »

SBolgov wrote:
Sabina wrote:Так тут тот же SELECT DISTINCT для текст поля Table1.Description ..
Или я чего-то недопонимаю?

Пардон, опечатка. :oops: Уже исправил.

Разумеется, DISTINCT должен быть только во внутреннем SELECT, а не во внешнем.

Сабина, спасибо! ;)


Ну а толку делать внутренний distinct если при join Table1 дублированые записи опять расплодятся.
IMHO не катит
Никакой разрухи нет. (с) Проф. Преображенский.

Return to “Вопросы и новости IT”