powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / SELECT DISTINCT
19 сообщений из 19, страница 1 из 1
SELECT DISTINCT
    #38853654
Людмila
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имеется Таблица с полем Name, так вот его удивительное содержимое!
"Лариса~Влад~Николай"
"Борис"
"Андрей~Николай~Борис"

ну никак не могу сообразить как вытащить эти имена, чтобы в результате они были по одному и не повторялись
типа SELECT DISTINCT ......... в результате:
"Лариса"
"Влад"
"Николай"
"Борис"
"Андрей"

Может посоветуете что, по существу
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38853742
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SELECT`ами никак из этой каши не вытащить, сначала надо данные нормализовать.

Как вариант примерно так:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
create curcor result (cName c(30))
index on cName tag cName
sele MyTable
scan
	for i = 1 to GetWordCount(MyTable.Name, '~')
		lcName = padr(GetWordNum(lcAll, i, '~'), 30)
		if !empty(lcName) and !IndexSeek(lcName, .F., 'result', 'cName')
			insert into result (cName) values (lcName)
		endif
	endfor
endscan

sele result
brow
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38853748
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя я полностью согласен с тем, что Dima Tсначала надо данные нормализовать., тем не менее Dima TSELECT`ами никак из этой каши не вытащить вытащить можно:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Create Cursor t1 (names varchar(100))
Insert into t1 values ("Лариса~Влад~Николай")
Insert into t1 values ("Борис")
Insert into t1 values ("Андрей~Николай~Борис")
Create Cursor t2 (i int)
Insert into t2 values (1)
Insert into t2 values (2)
Insert into t2 values (3)
-- в t2 надо воткнуть столько записей, сколько максимально может быть имён в одной записи исходной таблицы
Select distinct Cast(getwordnum(t1.names,t2.i,'~') as varchar(100)) as qwe from t1 join t2 on .t.


О производительности, ясное дело, говорить тут не приходится.
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38853760
Crispy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да мне кажется можно и проще.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Create Cursor t1 (names varchar(100))
Insert into t1 values ("Лариса~Влад~Николай")
Insert into t1 values ("Борис")
Insert into t1 values ("Андрей~Николай~Борис")

* Сначала обработать записи:

REPLACE names WITH STRTRAN(names,"~",CHR(13)+CHR(10)) ALL 

* а затем через промежуточный вывод растащить по одной:

COPY TO tmp.txt SDF 
ZAP 
APPEND FROM tmp.txt FIELDS names SDF 

BROWSE LAST 

* ну а дальше уже и делать уникальными любым способом:

SELECT DISTINCT * FROM t1 ORDER BY names INTO CURSOR t2

BROWSE LAST 
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38853889
Людмila
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пока сотворила и пользуюсь вариантом:

* Выбираем первые - getwordnum(name, 1 ,'~')
Select Cast(getwordnum(name, 1 ,'~') as C(10)) as qwe from Tab1 TABLE Tmp

* Зная, что максимум сочетаний - 6 запускаю цикл (с 2-ки т.к. 1-е уже в Tmp)
FOR I=2 TO 6
INSERT INTO Tmp (qwe) SELECT Cast(GETWORDNUM(NAME, I ,'~') as C(10)) from Tab1 WHERE GETWORDCOUNT(Name,'~')> I-1
NEXT

* Тет самым получаю Все имени
* Ну и затем в архив с соблюдением уникальности
SELECT DISTINCT qwe FROM Tmp INTO ARRAY ss

* 5 строчек кода, о производительности молчу (
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38853936
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Людмila,

а нафига цикл с i=2 ? имхо на гетвордкаунте потеряется больше времени, чем на добавление пустых записей в курсор... тем более что всё равно потом дистинктом проходите

Код: sql
1.
2.
3.
4.
5.
FOR I=1 TO 6
INSERT INTO Tmp (qwe) SELECT Cast(GETWORDNUM(NAME,I,'~') as C(10)) from Tab1
NEXT

SELECT DISTINCT qwe FROM Tmp where !empty(qwe) INTO ARRAY ss
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38853964
Людмila
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну первый Select - создает Tab1 с первыми Именами (в вашем варианте Тав1 придется все равно Create Table)
поэтому For I=2 to 6
вставляем в Тав1 - уже вторые и последующие имена, по-моему так быстрее.

на производительность протестирую все варианты (попозже)
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38854065
sg12
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Людмila

Попробуйте так:
SELECT * FROM (SELECT PADR(GETWORDNUM(field1,1,'~'),20) FROM table1;
UNION SELECT PADR(GETWORDNUM(field1,2,'~'),20) FROM table1 ;
UNION SELECT PADR(GETWORDNUM(field1,3,'~'),20) FROM table1) ;
AS query1 WHERE !EMPTY(exp_1)
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38854120
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Людмilaна производительность протестирую все вариантыесли там не сотни тысяч записей, то навряд ли разница будет заметна
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38856541
Людмila
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вариант от sg12 тоже работает и более всех - в духе SQL!
протестировать на производительность пока нет возможности - всего около 50 записей, ну и затраченное время естественно 0.00 sec во всех вариантах.
Как бы то ни было, на мой взгляд, последний вариант рулит!
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38856567
sg12
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ЛюдмilaВариант от sg12 тоже работает и более всех - в духе SQL!
протестировать на производительность пока нет возможности - всего около 50 записей, ну и затраченное время естественно 0.00 sec во всех вариантах.
Как бы то ни было, на мой взгляд, последний вариант рулит!

При больших таблицах SCAN эффективнее, чем SELECT.
Вообще-то все эти решения совершенно равнозначны, по обстоятельствам.
Нужно только немного упорядочить коды, вам в коллекцию:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
* Имеется таблица с полем, где данные разделены символом-разделителем.
* Требуется извлечь данные, чтобы в результате они были по одному и не повторялись.

CREATE CURSOR table1 (field1 C(100))
INSERT INTO table1 VALUES ("Лариса~Влад~Николай")
INSERT INTO table1 VALUES ("Борис")
INSERT INTO table1 VALUES ("Андрей~Николай~Борис")

LOCAL lcSymbol,lnCount,i
lcSymbol = '~'
lnCount = 3

CREATE CURSOR cur1 (field1 C(20))
SELECT table1
SCAN
	FOR i = 1 TO GETWORDCOUNT(table1.field1,lcSymbol)
		INSERT INTO cur1 (field1) VALUES (GETWORDNUM(table1.field1,i,lcSymbol))
	ENDFOR
ENDSCAN
SELECT DISTINCT field1 FROM cur1 WHERE !EMPTY(field1) ORDER BY field1

CREATE CURSOR cur1 (field1 C(20))
FOR i=1 TO lnCount
	INSERT INTO cur1 (field1) SELECT PADR(GETWORDNUM(table1.field1,i,lcSymbol),20) FROM table1
ENDFOR
SELECT DISTINCT field1 FROM cur1 WHERE !EMPTY(field1) ORDER BY field1

SELECT field1 FROM table1 INTO CURSOR cur1 READWRITE
REPLACE ALL field1 WITH STRTRAN(field1,"~",CHR(13)+CHR(10))
COPY TO tmp.txt SDF
CREATE CURSOR cur1 (field1 C(20))
APPEND FROM tmp.txt FIELDS field1 SDF
SELECT DISTINCT field1 FROM cur1 WHERE !EMPTY(field1) ORDER BY field1

CREATE CURSOR tableInt (idTab INT)
FOR i = 1 TO lnCount
	INSERT INTO tableInt VALUES (i)
ENDFOR
SELECT exp_1 AS field1 FROM ;
	(SELECT DISTINCT CAST(GETWORDNUM(table1.field1,tableInt.idTab,lcSymbol) AS C(20)) ;
	FROM table1 JOIN tableInt ON .T.) ;
	AS query1 WHERE !EMPTY(exp_1)

CREATE CURSOR cur1 (field1 C(20))
FOR i = 1 TO lnCount
	SELECT field1 FROM cur1 ;
		UNION SELECT PADR(GETWORDNUM(field1,i,lcSymbol),20) FROM table1 ;
		INTO CURSOR cur1 READWRITE
ENDFOR
SELECT field1 FROM cur1 WHERE !EMPTY(field1)

SELECT exp_1 AS field1 ;
	FROM (SELECT PADR(GETWORDNUM(field1,1,lcSymbol),20) FROM table1;
	UNION SELECT PADR(GETWORDNUM(field1,2,lcSymbol),20) FROM table1 ;
	UNION SELECT PADR(GETWORDNUM(field1,3,lcSymbol),20) FROM table1) ;
	AS query1 WHERE !EMPTY(exp_1)

...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38856605
Людмila
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Очень признательна!
Большое спасибо!
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38856632
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Людмilaи более всех - в духе SQL!
SQL в чистом виде тут не уместен. SQL предполагает что данные нормализованы согласно правилам реляционных БД, чего в данном случае нет.
Поэтому конкретно в этом случае для использования только SQL надо заложить жесткое ограничение на количество имен в одной строке. Например 6. Что будет если в рабочем коде появится строка где имен 7 или 8 ? Зачем закладывать такие "мины" в код?
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38856669
sg12
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TЛюдмilaи более всех - в духе SQL!
SQL в чистом виде тут не уместен. SQL предполагает что данные нормализованы согласно правилам реляционных БД, чего в данном случае нет.
Поэтому конкретно в этом случае для использования только SQL надо заложить жесткое ограничение на количество имен в одной строке. Например 6. Что будет если в рабочем коде появится строка где имен 7 или 8 ? Зачем закладывать такие "мины" в код?

Подсчитать количество имен вы можете хотя бы так:
SELECT MAX(OCCURS('~',field1)) + 1 FROM table1

О нормализации у вас странные понятия.
Например, вас можно понять так, что по вашим представлениям полей вида ФИО (Иванов Петр Сергеевич) не может быть, т.к. данные разделены пробелом.
Или, в списках отделов кадров полно бывает не только тезок, но и полных однофамильцев.
Эта же таблица с именами вполне может быть списком детей по группам в детском садике на новогодние открытки, что по вашим понятием недопустимо.
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38856756
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sg12Подсчитать количество имен вы можете хотя бы так:
SELECT MAX(OCCURS('~',field1)) + 1 FROM table1
Могу, а дальше как задачу средствами SQL ?

Никак, потому что SQL работает на нормализованных данных. Поэтому их надо сначала как-то нормализовать другими средствами, а затем применять SQL.

sg12О нормализации у вас странные понятия.
Это не мои понятия, это основы реляционных БД. Бери любую книгу по любой СУБД и в начале будет следущее:
https://ru.wikipedia.org/wiki/Первая_нормальная_форма Определение

Переменная отношения находится в первой нормальной форме тогда и только тогда, когда в любом допустимом значении отношения каждый его кортеж содержит только одно значение для каждого из атрибутов
Это основы, которые должны быть соблюдены. В данном случае это правило нарушено: один кортеж (запись) содержит несколько значений (имен). Поэтому возникает проблема применения SQL к этим данным.
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38856779
tanglir
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Людмilaи более всех - в духе SQL! а почему мой вариант вам показался "менее в духе скл"?
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38856819
sg12
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tsg12Подсчитать количество имен вы можете хотя бы так:
SELECT MAX(OCCURS('~',field1)) + 1 FROM table1
Могу, а дальше как задачу средствами SQL ?

Никак, потому что SQL работает на нормализованных данных. Поэтому их надо сначала как-то нормализовать другими средствами, а затем применять SQL.

sg12О нормализации у вас странные понятия.
Это не мои понятия, это основы реляционных БД. Бери любую книгу по любой СУБД и в начале будет следущее:
https://ru.wikipedia.org/wiki/Первая_нормальная_форма Определение

Переменная отношения находится в первой нормальной форме тогда и только тогда, когда в любом допустимом значении отношения каждый его кортеж содержит только одно значение для каждого из атрибутов
Это основы, которые должны быть соблюдены. В данном случае это правило нарушено: один кортеж (запись) содержит несколько значений (имен). Поэтому возникает проблема применения SQL к этим данным.

Копируете вы красиво. Только где вы там увидели подтверждение ваших утверждений.
Вы путаете ваш термин "несколько значений (имен)" с именами людей, это не одно и тоже.
Поля таблиц могут содержать достаточно сложное выражение, и не только символьное или какое, но и составное, и вычисляемое.
Эта таблица соответствует вашему условию - пририсуйте индексное поле, для наглядности, и проблемы ваши исчезнут.
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38856832
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sg12Копируете вы красиво. Только где вы там увидели подтверждение ваших утверждений.
Я выше не увидел опровержение моих утверждений. Приведи, обсудим.

PS Извини, своболудием не болею, флудить тебе придется в одиночестве.
...
Рейтинг: 0 / 0
SELECT DISTINCT
    #38856893
sg12
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima Tsg12Копируете вы красиво. Только где вы там увидели подтверждение ваших утверждений.
Я выше не увидел опровержение моих утверждений. Приведи, обсудим.

PS Извини, своболудием не болею, флудить тебе придется в одиночестве.

Привычное вам обзывательства вам ближе. Я уже указывал, где вы путаетесь и вы снова "приведи".
Два разных SQL у вас под носом, а вы все "никак".

Пример:
Есть такой тип поля - DateTime. Оно содержит в себе разделенные разделителями и вычисляемые с помощью функций год, месяц, день, час, минуты, секунды, а также AM/PM, день недели, високосность года, может еще-что.
Т.е. по вашим понятиям это "имена", но вас это устраивает.
С чего вы решили, что такое качество присуще только этому типу поля?

Теперь об "основах", которыми вы козырнули.
Когда дают ссылки типа вашей (или на MSDN, Microsoft и т.п.), то часто это означает, что автор ссылки сам не может в ней разобраться и хотел бы разъяснений.

Переведем вами скопированную цитату на привычный язык:
Таблица находится в первой нормальной форме тогда и только тогда, когда каждая строка содержит только одно значение для каждого столбца.
И что из этой фразы следует, что вы хотели доказать?
Интересно, а в Фоксе есть вообще такая возможность (.dbf ведь не таблица Excel)?

Из Хелпа:
Поля типа Character могут содержать различную символьную информацию: символы, цифры, знаки и прочее, но не могут быть использованы в арифметических и математических вычислениях;

Вот строка из таблицы, все согласно Хелп, даже без прочих:
lcString = "Лариса~Влад~Николай"
Вас что, символ '~' в ней раздражает? А если вместо него будет пробел, подчеркивание, тире или запятая, то тогда как?
Хотя бы функцию UPPER() можно применить?
SELECT UPPER(field1) FROM table1

Для упражнений:
В выражениях: 'Северо-восток Южного Вьетнама' или 'Земля Франса-Иосифа' или 'Штат Новый Орлеан' - сколько "ваших" имен?
А здесь: 'Александр Дюма.Три мушетера' или 'Иван Сергеевич Тургенев' или 'Иванов,Иван,Иванович'?
Сколько "имен" в строке: 'Паспорт выдан Ивановским ОВД г.Алешкино Сергеевской области'?

Пример:
Если в поле таблицы будут храниться различные алфавиты, вы будете требовать, чтобы каждую букву по вашему образцу "нормализовали", прежде чем ее оттуда извлечь?
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / SELECT DISTINCT
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]