Как получить таблицу с уникальными значениями столбцов?

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Vijon
Новичок
Новичок
 
Сообщения: 29
Зарегистрирован: 10.05.2006 (Ср) 17:19

Как получить таблицу с уникальными значениями столбцов?

Сообщение Vijon » 27.10.2006 (Пт) 20:15

То есть, дана некая исходная таблица TableNotUnique. В ней есть столбец PotentialUnique.

Задача: перекачать данные из TableNotUnique в другую таблицу TableUnique, таким образом, чтобы в новой таблице значения столбца PotentialUnique были бы уникальными.

Вобще-то, самый тупой способ выглядит примерно так...

Dim TableUnique As New DataTable
TableUnique = TableNotUnique.Clone
TableUnique.Columns("PotentialUnique").Unique = True
Dim rows As DataRow() = TableNotUnique.Select()
Dim row As DataRow
For Each row In rows
Try
Dim row2 As DataRow = TableUnique.NewRow
row2.BeginEdit()
row2 ("PotentialUnique") = row("PotentialUnique")
'--------------------- Other fields ------------
row2.EndEdit()
TableUnique.Rows.Add(row2)
Catch ex As Exception
End Try
Next row
TableUnique.AcceptChanges()


Но нельзя ли сделать все как-то попроще, одним движением.

Спасибо.

Thomas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 246
Зарегистрирован: 12.11.2005 (Сб) 0:17
Откуда: "Сказочное королевство"

Сообщение Thomas » 27.10.2006 (Пт) 23:50

SELECT DISTINCT

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 28.10.2006 (Сб) 0:01

Как сказал Томас - SELECT DISTINCT - это решение. Если таблицы с совпадающими полями, то вообще проблем нет - выполняете запрос в базе:

Код: Выделить всё
INSERT INTO TableUnique SELECT DISTINCT Field1, Field2 FROM TableNotUnique


Если без поля PotentialUnique нельзя, то

Код: Выделить всё
INSERT INTO TableUnique SELECT DISTINCT Field1, Field2, PotentialUnique FROM TableNotUnique


Правда, если для одной и той же строки с разным PotentialUnique могут быть разные данные, то они в этом случае тоже выбирутся. И вообще решение с колонкой PotentialUnique странное - данные могут повторяться? Если да, то каким образом выставляется флаг PotentionalUnique?
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

Vijon
Новичок
Новичок
 
Сообщения: 29
Зарегистрирован: 10.05.2006 (Ср) 17:19

Сообщение Vijon » 28.10.2006 (Сб) 21:20

В данном случае речь идет об операциях только с объектами DataTable, то есть, без SQL-запросов непосредственно к БД.

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 28.10.2006 (Сб) 22:32

Сначала нашел код, но, как оказалось, он не совсем рабочий. Написал свой. Отличие от Вашего в том, что можно выбирать по имени любой колонки (т.е. DISTINCT делать по любой колонке).

Код: Выделить всё

    Public Shared Function SelectDistinctRows(ByVal table As DataTable, ByVal column As String) As DataTable

        Dim result As New DataTable

        ' Create rows
        For i As Integer = 0 To table.Columns.Count - 1
            Dim col As DataColumn = table.Columns(i)
            result.Columns.Add(col.ColumnName, col.DataType)
        Next

        Dim cList As New List(Of String)

        For Each row As DataRow In table.Rows
            If Not cList.Contains(row(column)) Then
                cList.Add(row(column))
                Dim nRow As DataRow = result.NewRow()

                For i As Integer = 0 To result.Columns.Count - 1
                    nRow(i) = row(i)
                Next
                result.Rows.Add(nRow)
            End If
        Next

        Return result

    End Function

The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

Thomas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 246
Зарегистрирован: 12.11.2005 (Сб) 0:17
Откуда: "Сказочное королевство"

Сообщение Thomas » 29.10.2006 (Вс) 11:28

gaidar

Dim cList As New List(Of String) -- ???

A можно так?
Dim cList As New SortedList :?:

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 29.10.2006 (Вс) 14:24

Thomas - это Generic List.

Можно, конечно, использовать и не Generic, а List для object, но тогда производительность при больших объемах падает из-за необходимости приведения типов.

Статью про Generics для VBStreets я давно написал, но еще не опубликовал :). Дойдут руки - опубликую.
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

Vijon
Новичок
Новичок
 
Сообщения: 29
Зарегистрирован: 10.05.2006 (Ср) 17:19

Сообщение Vijon » 29.10.2006 (Вс) 15:03

Ну я тоже вот наваял...

Function GetUniqueTable(ByVal dt As DataTable, ByVal cols As
DataColumn()) As DataTable
GetUniqueTable = New DataTable
Dim col As DataColumn
For Each col In cols
GetUniqueTable.Columns.Add(col)
Next col
Dim uc As New UniqueConstraint("uc", cols)
GetUniqueTable.Constraints.Add(uc)
Dim row As DataRow
Dim rows As DataRow() = dt.Select
For Each row In rows
Try
GetUniqueTable.ImportRow(row)
Catch ex As Exception
End Try
Next row
GetUniqueTable.AcceptChanges()
End Function


Преймущество тут в том, что не надо присваивать каждое поле в отдельности.

Все это здорово... Однако, я надеялся найти какую-нибудь системную функцию, которая одним движением превращала бы "неуникальную" таблицу в "уникальную".

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 29.10.2006 (Вс) 23:21

Боюсь, что такой функции нет. Просто потому, что это задача слоя базы данных...
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

mnzol
Новичок
Новичок
 
Сообщения: 34
Зарегистрирован: 29.09.2004 (Ср) 11:02

Сообщение mnzol » 01.11.2006 (Ср) 11:14

Я делаю так (извиняюсь за C#):

Код: Выделить всё
DataTable TableUnique = TableNotUnique.Clone();

DataColumn[] cclKeyColumns = new DataColumn[1];
cclKeyColumns[0] = TableUnique.Columns["SourceCode"];
TableUnique.PrimaryKey = cclKeyColumns;

TableUnique.Merge(TableNotUnique);


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 99

    TopList