Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/SQL в Excel. Операции с множествами - Мир MS Excel

Старая форма входа
  • Страница 1 из 2
  • 1
  • 2
  • »
Модератор форума: _Boroda_, китин  
SQL в Excel. Операции с множествами
nerv Дата: Суббота, 06.04.2013, 15:51 | Сообщение № 1
Группа: Редакторы
Ранг: Обитатель
Сообщений: 431
Репутация: 193 ±
Замечаний: 0% ±

Всем привет

Интересуют операции с множествами. Есть такой код:
[vba]
Код
' Объединить
Sub Union()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] UNION SELECT * FROM [Лист1$B1:B5];")
     Range("D1").CopyFromRecordset ADO.Recordset
End Sub

' Объединить все
Sub UnionAll()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] UNION ALL SELECT * FROM [Лист1$B1:B5];")
     Range("F1").CopyFromRecordset ADO.Recordset
End Sub

' Пересечение
Sub Intersect()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] INTERSECT SELECT * FROM [Лист1$B1:B5];")
     Range("H1").CopyFromRecordset ADO.Recordset
End Sub

' Разность
Sub Except()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] EXCEPT SELECT * FROM [Лист1$B1:B5];")
     Range("J1").CopyFromRecordset ADO.Recordset
End Sub

' Разность все
Sub ExceptAll()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] EXCEPT ALL SELECT * FROM [Лист1$B1:B5];")
     Range("L1").CopyFromRecordset ADO.Recordset
End Sub
[/vba]
Корректно отрабатывают только операции объединения UNION и UNION ALL. Интересует, можно ли эмулировать остальные операции в sql excel?

Спасибо.
К сообщению приложен файл: set_operations.xls (45.0 Kb)


Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


YM 41001156540584 / WM WMR R21924176233

https://github.com/nervgh/vba
 
Ответить
СообщениеВсем привет

Интересуют операции с множествами. Есть такой код:
[vba]
Код
' Объединить
Sub Union()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] UNION SELECT * FROM [Лист1$B1:B5];")
     Range("D1").CopyFromRecordset ADO.Recordset
End Sub

' Объединить все
Sub UnionAll()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] UNION ALL SELECT * FROM [Лист1$B1:B5];")
     Range("F1").CopyFromRecordset ADO.Recordset
End Sub

' Пересечение
Sub Intersect()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] INTERSECT SELECT * FROM [Лист1$B1:B5];")
     Range("H1").CopyFromRecordset ADO.Recordset
End Sub

' Разность
Sub Except()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] EXCEPT SELECT * FROM [Лист1$B1:B5];")
     Range("J1").CopyFromRecordset ADO.Recordset
End Sub

' Разность все
Sub ExceptAll()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] EXCEPT ALL SELECT * FROM [Лист1$B1:B5];")
     Range("L1").CopyFromRecordset ADO.Recordset
End Sub
[/vba]
Корректно отрабатывают только операции объединения UNION и UNION ALL. Интересует, можно ли эмулировать остальные операции в sql excel?

Спасибо.

Автор - nerv
Дата добавления - 06.04.2013 в 15:51
M73568 Дата: Суббота, 06.04.2013, 20:29 | Сообщение № 2
Группа: Проверенные
Ранг: Форумчанин
Сообщений: 197
Репутация: 46 ±
Замечаний: 0% ±

2007-2013
Если вот так попробовать?
[vba]
Код
' Объединить
Sub Union()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] UNION SELECT * FROM [Лист1$B1:B5];")
     Range("D1").CopyFromRecordset ADO.Recordset
End Sub

' Объединить все
Sub UnionAll()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] UNION ALL SELECT * FROM [Лист1$B1:B5];")
     Range("F1").CopyFromRecordset ADO.Recordset
End Sub

' Пересечение
Sub Intersect()
     Dim ADO As New ADO
     ADO.Query ("SELECT [Лист1$A1:A9].F1 FROM [Лист1$A1:A9] left join [Лист1$B1:B5] on [Лист1$A1:A9].[F1] = [Лист1$B1:B5].[F1] where [Лист1$B1:B5].[F1] is not null;")
     Range("H1").CopyFromRecordset ADO.Recordset
End Sub

' Разность
Sub Except()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] left join [Лист1$B1:B5] on [Лист1$A1:A9].[F1] = [Лист1$B1:B5].[F1] where [Лист1$B1:B5].[F1] is null;")
     Range("J1").CopyFromRecordset ADO.Recordset
End Sub

' Разность все
Sub ExceptAll()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] left join [Лист1$B1:B5] on [Лист1$A1:A9].[F1] = [Лист1$B1:B5].[F1] where [Лист1$B1:B5].[F1] is null " & _
                "      union " & _
                "SELECT * FROM [Лист1$B1:B5] left join [Лист1$A1:A9] on [Лист1$B1:B5].[F1] = [Лист1$A1:A9].[F1] where [Лист1$A1:A9].[F1] is null ;")
     Range("L1").CopyFromRecordset ADO.Recordset
End Sub
[/vba]
 
Ответить
СообщениеЕсли вот так попробовать?
[vba]
Код
' Объединить
Sub Union()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] UNION SELECT * FROM [Лист1$B1:B5];")
     Range("D1").CopyFromRecordset ADO.Recordset
End Sub

' Объединить все
Sub UnionAll()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] UNION ALL SELECT * FROM [Лист1$B1:B5];")
     Range("F1").CopyFromRecordset ADO.Recordset
End Sub

' Пересечение
Sub Intersect()
     Dim ADO As New ADO
     ADO.Query ("SELECT [Лист1$A1:A9].F1 FROM [Лист1$A1:A9] left join [Лист1$B1:B5] on [Лист1$A1:A9].[F1] = [Лист1$B1:B5].[F1] where [Лист1$B1:B5].[F1] is not null;")
     Range("H1").CopyFromRecordset ADO.Recordset
End Sub

' Разность
Sub Except()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] left join [Лист1$B1:B5] on [Лист1$A1:A9].[F1] = [Лист1$B1:B5].[F1] where [Лист1$B1:B5].[F1] is null;")
     Range("J1").CopyFromRecordset ADO.Recordset
End Sub

' Разность все
Sub ExceptAll()
     Dim ADO As New ADO
     ADO.Query ("SELECT * FROM [Лист1$A1:A9] left join [Лист1$B1:B5] on [Лист1$A1:A9].[F1] = [Лист1$B1:B5].[F1] where [Лист1$B1:B5].[F1] is null " & _
                "      union " & _
                "SELECT * FROM [Лист1$B1:B5] left join [Лист1$A1:A9] on [Лист1$B1:B5].[F1] = [Лист1$A1:A9].[F1] where [Лист1$A1:A9].[F1] is null ;")
     Range("L1").CopyFromRecordset ADO.Recordset
End Sub
[/vba]

Автор - M73568
Дата добавления - 06.04.2013 в 20:29
Gustav Дата: Суббота, 06.04.2013, 22:27 | Сообщение № 3
Группа: Админы
Ранг: Участник клуба
Сообщений: 2808
Репутация: 1183 ±
Замечаний: ±

начинал с Excel 4.0, видел 2.1
Цитата (M73568)
' Пересечение
Sub Intersect()
Dim ADO As New ADO
ADO.Query ("SELECT [Лист1$A1:A9].F1 FROM [Лист1$A1:A9] left join [Лист1$B1:B5] on [Лист1$A1:A9].[F1] = [Лист1$B1:B5].[F1] where [Лист1$B1:B5].[F1] is not null;")
Range("H1").CopyFromRecordset ADO.Recordset
End Sub

Здесь можно попроще - с INNER JOIN и без WHERE:
[vba]
Код
ADO.Query "SELECT a.F1 FROM [Лист1$A1:A9] a INNER JOIN [Лист1$B1:B5] b ON a.F1 = b.F1"
[/vba]


МОИ: Ник, Tip box: 41001663842605
 
Ответить
Сообщение
Цитата (M73568)
' Пересечение
Sub Intersect()
Dim ADO As New ADO
ADO.Query ("SELECT [Лист1$A1:A9].F1 FROM [Лист1$A1:A9] left join [Лист1$B1:B5] on [Лист1$A1:A9].[F1] = [Лист1$B1:B5].[F1] where [Лист1$B1:B5].[F1] is not null;")
Range("H1").CopyFromRecordset ADO.Recordset
End Sub

Здесь можно попроще - с INNER JOIN и без WHERE:
[vba]
Код
ADO.Query "SELECT a.F1 FROM [Лист1$A1:A9] a INNER JOIN [Лист1$B1:B5] b ON a.F1 = b.F1"
[/vba]

Автор - Gustav
Дата добавления - 06.04.2013 в 22:27
ikki Дата: Суббота, 06.04.2013, 22:47 | Сообщение № 4
Группа: Друзья
Ранг: Старожил
Сообщений: 1906
Репутация: 504 ±
Замечаний: 0% ±

Excel 2003, 2010
AS не нужен?


помощь по Excel и VBA
ikki@fxmail.ru, icq 592842413, skype alex.ikki
 
Ответить
СообщениеAS не нужен?

Автор - ikki
Дата добавления - 06.04.2013 в 22:47
Gustav Дата: Суббота, 06.04.2013, 23:15 | Сообщение № 5
Группа: Админы
Ранг: Участник клуба
Сообщений: 2808
Репутация: 1183 ±
Замечаний: ±

начинал с Excel 4.0, видел 2.1
Цитата (ikki)
AS не нужен?

Ну, у меня не ругалось. Вроде, в Jet'е для псевдонимов таблиц он необязателен, а для псевдонимов полей - обязателен. Короче, я всегда экпериментально проверяю конкретные случаи smile


МОИ: Ник, Tip box: 41001663842605
 
Ответить
Сообщение
Цитата (ikki)
AS не нужен?

Ну, у меня не ругалось. Вроде, в Jet'е для псевдонимов таблиц он необязателен, а для псевдонимов полей - обязателен. Короче, я всегда экпериментально проверяю конкретные случаи smile

Автор - Gustav
Дата добавления - 06.04.2013 в 23:15
ikki Дата: Суббота, 06.04.2013, 23:19 | Сообщение № 6
Группа: Друзья
Ранг: Старожил
Сообщений: 1906
Репутация: 504 ±
Замечаний: 0% ±

Excel 2003, 2010
Цитата (Gustav)
Короче, я всегда экпериментально проверяю конкретные случаи

угум, это хорошая практика.
а я иногда разгильдяйничаю. sad


помощь по Excel и VBA
ikki@fxmail.ru, icq 592842413, skype alex.ikki
 
Ответить
Сообщение
Цитата (Gustav)
Короче, я всегда экпериментально проверяю конкретные случаи

угум, это хорошая практика.
а я иногда разгильдяйничаю. sad

Автор - ikki
Дата добавления - 06.04.2013 в 23:19
nerv Дата: Суббота, 06.04.2013, 23:55 | Сообщение № 7
Группа: Редакторы
Ранг: Обитатель
Сообщений: 431
Репутация: 193 ±
Замечаний: 0% ±

пересечение
Цитата (M73568)
[vba]
Код
"SELECT [Лист1$A1:A9].F1 FROM [Лист1$A1:A9] left join [Лист1$B1:B5] on [Лист1$A1:A9].[F1] = [Лист1$B1:B5].[F1] where [Лист1$B1:B5].[F1] is not null;"
[/vba]


разность
Цитата (M73568)
[vba]
Код
"SELECT * FROM [Лист1$A1:A9] left join [Лист1$B1:B5] on [Лист1$A1:A9].[F1] = [Лист1$B1:B5].[F1] where [Лист1$B1:B5].[F1] is null;"
[/vba]


не понял в чем разница smile Запускал, результат работы разный. Разве
[vba]
Код
"SELECT [Лист1$A1:A9].F1 FROM [Лист1$A1:A9]"
[/vba]
и
[vba]
Код
"SELECT * FROM [Лист1$A1:A9]"
[/vba]
не одно и тоже?

Мда, однако, много букв получается вместо простых (как казалось бы) команд.

Еще хотелось бы услышать объяснения, как работает LEFT JOIN и нафига
[vba]
Код
"where [Лист1$B1:B5].[F1] is null;"
[/vba]
?

Читал, что лефт джоин создает таблицу, но как то непонятно было написано.

Кстати, всем спасибо за ответы smile


Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


YM 41001156540584 / WM WMR R21924176233

https://github.com/nervgh/vba
 
Ответить
Сообщениепересечение
Цитата (M73568)
[vba]
Код
"SELECT [Лист1$A1:A9].F1 FROM [Лист1$A1:A9] left join [Лист1$B1:B5] on [Лист1$A1:A9].[F1] = [Лист1$B1:B5].[F1] where [Лист1$B1:B5].[F1] is not null;"
[/vba]


разность
Цитата (M73568)
[vba]
Код
"SELECT * FROM [Лист1$A1:A9] left join [Лист1$B1:B5] on [Лист1$A1:A9].[F1] = [Лист1$B1:B5].[F1] where [Лист1$B1:B5].[F1] is null;"
[/vba]


не понял в чем разница smile Запускал, результат работы разный. Разве
[vba]
Код
"SELECT [Лист1$A1:A9].F1 FROM [Лист1$A1:A9]"
[/vba]
и
[vba]
Код
"SELECT * FROM [Лист1$A1:A9]"
[/vba]
не одно и тоже?

Мда, однако, много букв получается вместо простых (как казалось бы) команд.

Еще хотелось бы услышать объяснения, как работает LEFT JOIN и нафига
[vba]
Код
"where [Лист1$B1:B5].[F1] is null;"
[/vba]
?

Читал, что лефт джоин создает таблицу, но как то непонятно было написано.

Кстати, всем спасибо за ответы smile

Автор - nerv
Дата добавления - 06.04.2013 в 23:55
Gustav Дата: Воскресенье, 07.04.2013, 00:53 | Сообщение № 8
Группа: Админы
Ранг: Участник клуба
Сообщений: 2808
Репутация: 1183 ±
Замечаний: ±

начинал с Excel 4.0, видел 2.1
Цитата (nerv)
не одно и тоже?

одно и то же
Цитата (nerv)
результат работы разный

потому что в первом is not null, а во втором - is null.
Цитата (nerv)
как работает LEFT JOIN

Сначала отбирает все записи из левой таблицы (во временный набор), потом приставляет к ним (в этом временном наборе) совпадающие записи из правой таблицы (совпадающие - по связующему полю ON...). Там, где совпадений не находится, справа (во временном наборе) ставится null. Далее, чтобы найти записи левой таблицы, не имеющие связи с правой таблицей, просто выбираем те записи, у которых справа null.


МОИ: Ник, Tip box: 41001663842605
 
Ответить
Сообщение
Цитата (nerv)
не одно и тоже?

одно и то же
Цитата (nerv)
результат работы разный

потому что в первом is not null, а во втором - is null.
Цитата (nerv)
как работает LEFT JOIN

Сначала отбирает все записи из левой таблицы (во временный набор), потом приставляет к ним (в этом временном наборе) совпадающие записи из правой таблицы (совпадающие - по связующему полю ON...). Там, где совпадений не находится, справа (во временном наборе) ставится null. Далее, чтобы найти записи левой таблицы, не имеющие связи с правой таблицей, просто выбираем те записи, у которых справа null.

Автор - Gustav
Дата добавления - 07.04.2013 в 00:53
nerv Дата: Понедельник, 08.04.2013, 01:43 | Сообщение № 9
Группа: Редакторы
Ранг: Обитатель
Сообщений: 431
Репутация: 193 ±
Замечаний: 0% ±

Gustav, спасибо!

Если честно, пока смутно представляю возможности SQL.

Допустим, есть Таблица с одним полем. В этом поле 4-е строки:
Петя
Маша
Петя
Вася

Sql может вернуть кол-во каждой записи в поле? Т.е.
Петя - 2
Маша - 1
Петя - 2
Вася - 1
?

Или он для этого не предназначен и это делается в цикле в "другой" программе? Хотя инет говорит, что в SQL тоже есть циклы...


Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


YM 41001156540584 / WM WMR R21924176233

https://github.com/nervgh/vba


Сообщение отредактировал nerv - Понедельник, 08.04.2013, 01:44
 
Ответить
СообщениеGustav, спасибо!

Если честно, пока смутно представляю возможности SQL.

Допустим, есть Таблица с одним полем. В этом поле 4-е строки:
Петя
Маша
Петя
Вася

Sql может вернуть кол-во каждой записи в поле? Т.е.
Петя - 2
Маша - 1
Петя - 2
Вася - 1
?

Или он для этого не предназначен и это делается в цикле в "другой" программе? Хотя инет говорит, что в SQL тоже есть циклы...

Автор - nerv
Дата добавления - 08.04.2013 в 01:43
ikki Дата: Понедельник, 08.04.2013, 02:27 | Сообщение № 10
Группа: Друзья
Ранг: Старожил
Сообщений: 1906
Репутация: 504 ±
Замечаний: 0% ±

Excel 2003, 2010
Цитата (nerv)
Петя - 2
Маша - 1
Петя - 2
Вася - 1

а так - зачем?

вариант
Петя - 2
Маша - 1
Вася - 1

получается легко
[vba]
Код
SELECT [name], COUNT([name]) FROM [tab] GROUP BY [name];
[/vba]

именно так, как у тебя - тоже можно.
например,
[vba]
Код
SELECT a.[name], c.[cnt]
FROM [tab] a LEFT JOIN (SELECT b.[name], COUNT(b.[name]) AS cnt FROM [tab] b GROUP BY b.[name]) c ON a.[name]=c.[name];
[/vba]
наверное, можно и как-нибудь проще (я не эксперт, еслечо)
но зачем? biggrin

пс. проверял оба запроса в аксе.


помощь по Excel и VBA
ikki@fxmail.ru, icq 592842413, skype alex.ikki


Сообщение отредактировал ikki - Понедельник, 08.04.2013, 03:26
 
Ответить
Сообщение
Цитата (nerv)
Петя - 2
Маша - 1
Петя - 2
Вася - 1

а так - зачем?

вариант
Петя - 2
Маша - 1
Вася - 1

получается легко
[vba]
Код
SELECT [name], COUNT([name]) FROM [tab] GROUP BY [name];
[/vba]

именно так, как у тебя - тоже можно.
например,
[vba]
Код
SELECT a.[name], c.[cnt]
FROM [tab] a LEFT JOIN (SELECT b.[name], COUNT(b.[name]) AS cnt FROM [tab] b GROUP BY b.[name]) c ON a.[name]=c.[name];
[/vba]
наверное, можно и как-нибудь проще (я не эксперт, еслечо)
но зачем? biggrin

пс. проверял оба запроса в аксе.

Автор - ikki
Дата добавления - 08.04.2013 в 02:27
M73568 Дата: Понедельник, 08.04.2013, 09:03 | Сообщение № 11
Группа: Проверенные
Ранг: Форумчанин
Сообщений: 197
Репутация: 46 ±
Замечаний: 0% ±

2007-2013
Цитата (Gustav)
Здесь можно попроще - с INNER JOIN и без WHERE:

Я просто привык писать левые джойны, inner практически редко использую (right join только когда лень переписать left join), тем более что можно обойтись простым = [vba]
Код
    ADO.Query "SELECT a.F1 FROM [Лист1$A1:A9] a, [Лист1$B1:B5] b where a.F1 = b.F1"
[/vba]
Тоже самое только порядок сортировки по правой таблице, но что мешает добавить ORDER BY a.F1 wink
Цитата (nerv)
Хотя инет говорит, что в SQL тоже есть циклы...

ЕМНИП циклы это больше для хранимых процедур, триггеров... в тот же Aссess их уже не вставишь
 
Ответить
Сообщение
Цитата (Gustav)
Здесь можно попроще - с INNER JOIN и без WHERE:

Я просто привык писать левые джойны, inner практически редко использую (right join только когда лень переписать left join), тем более что можно обойтись простым = [vba]
Код
    ADO.Query "SELECT a.F1 FROM [Лист1$A1:A9] a, [Лист1$B1:B5] b where a.F1 = b.F1"
[/vba]
Тоже самое только порядок сортировки по правой таблице, но что мешает добавить ORDER BY a.F1 wink
Цитата (nerv)
Хотя инет говорит, что в SQL тоже есть циклы...

ЕМНИП циклы это больше для хранимых процедур, триггеров... в тот же Aссess их уже не вставишь

Автор - M73568
Дата добавления - 08.04.2013 в 09:03
Gustav Дата: Понедельник, 08.04.2013, 12:38 | Сообщение № 12
Группа: Админы
Ранг: Участник клуба
Сообщений: 2808
Репутация: 1183 ±
Замечаний: ±

начинал с Excel 4.0, видел 2.1
Цитата (M73568)
right join только когда лень переписать left join

RIGHT JOIN я использую обычно по "концептуальным соображениям", т.е., например, когда сравниваются две таблицы, то делаю:

1. Общие записи с INNER JOIN.
2. Записи, встречающиеся только в первой ("левой") таблице - LEFT JOIN с null в "правой".
3. Записи, встречающиеся только во второй ("правой") таблице - RIGHT JOIN с null в "левой". Это можно написать и с LEFT JOIN, но тогда придется менять местами таблицы в тексте запроса.

Хотя, в общем, RIGHT JOIN это некоторое косметическое излишество. Некоторые системы прекрасно обходятся и без него, например, в так называемом Open SQL в SAP есть только INNER и LEFT.

Цитата (M73568)
SELECT a.F1 FROM [Лист1$A1:A9] a, [Лист1$B1:B5] b where a.F1 = b.F1

Так любит писать большинство программистов с большим опытом в больших системах типа Oracle. Особенно когда это нужно писать самому своими ручками. Тексты запросов, автоматически генерируемых в Access по QBE, исторически строятся с использованием JOIN. Собственно, и стандарт ANSI с некоторых пор рекомендует связи между таблицами помещать в JOIN, а все остальные условия - в WHERE. Но так хочется лениться и обходиться только секцией WHERE... wink


МОИ: Ник, Tip box: 41001663842605
 
Ответить
Сообщение
Цитата (M73568)
right join только когда лень переписать left join

RIGHT JOIN я использую обычно по "концептуальным соображениям", т.е., например, когда сравниваются две таблицы, то делаю:

1. Общие записи с INNER JOIN.
2. Записи, встречающиеся только в первой ("левой") таблице - LEFT JOIN с null в "правой".
3. Записи, встречающиеся только во второй ("правой") таблице - RIGHT JOIN с null в "левой". Это можно написать и с LEFT JOIN, но тогда придется менять местами таблицы в тексте запроса.

Хотя, в общем, RIGHT JOIN это некоторое косметическое излишество. Некоторые системы прекрасно обходятся и без него, например, в так называемом Open SQL в SAP есть только INNER и LEFT.

Цитата (M73568)
SELECT a.F1 FROM [Лист1$A1:A9] a, [Лист1$B1:B5] b where a.F1 = b.F1

Так любит писать большинство программистов с большим опытом в больших системах типа Oracle. Особенно когда это нужно писать самому своими ручками. Тексты запросов, автоматически генерируемых в Access по QBE, исторически строятся с использованием JOIN. Собственно, и стандарт ANSI с некоторых пор рекомендует связи между таблицами помещать в JOIN, а все остальные условия - в WHERE. Но так хочется лениться и обходиться только секцией WHERE... wink

Автор - Gustav
Дата добавления - 08.04.2013 в 12:38
Gustav Дата: Понедельник, 08.04.2013, 13:25 | Сообщение № 13
Группа: Админы
Ранг: Участник клуба
Сообщений: 2808
Репутация: 1183 ±
Замечаний: ±

начинал с Excel 4.0, видел 2.1
Цитата (nerv)
Хотя инет говорит, что в SQL тоже есть циклы...

Дело обстоит примерно так.

Существует классический SQL, в котором создается запрос и получается результат (ответ на запрос). С точки зрения наблюдателя (программиста) запрос это некий текст на формальном языке, который, будучи (каким-то образом, сейчас неважно каким) отправленным на выполнение, возвращает плоский набор данных (таблицу).

Для СУБД, которая выполняет запрос, его текст является командой. В процессе ее исполнения СУБД сама, незаметно для нас, осуществляет и циклы, и промежуточные хранения данных, и сортировку по Кнуту методом какого-нибудь пузырька и еще кучу всяких добрых дел. Мы от всего этого абстрагированы, просто в это время сидим, курим бамбук и ждём ответа на свой вопрос-запрос.

Не будь SQLя, мы бы все эти циклы и т.п. писали бы САМИ, как писали когда-то в эпоху Клиппера и первых версий dBase (если не еще "хуже", в смысле более подробно без специальных команд работы с данными).

И хотя "одним запросом" (а они могут быть невероятно сложные - у меня в Oracle бывали под 60K текста), можно сделать многое, но далеко не всё. К тому же, с увеличением сложности запроса затраты на его сопровождение возрастают в квадрате (говорю по собственному опыту).

С целью преодоления этих трудностей и были разработаны процедурные расширения SQL - специальные языки программирования, способные связать операции над множествами с обычными процедурными ("шаг за шагом") элементами программирования (циклами, условиями и т.п.), например, язык PL/SQL в Oracle или Transact-SQL в MS SQL Server.

А для неспецифических языков, например, для нашего любимого VBA, стали разрабатывать специальные библиотеки типа DAO или ADO. Поэтому на VBA мы теперь можем решать вполне SQL-ные задачи не хуже, чем на Transact-SQL.


МОИ: Ник, Tip box: 41001663842605

Сообщение отредактировал Gustav - Понедельник, 08.04.2013, 13:26
 
Ответить
Сообщение
Цитата (nerv)
Хотя инет говорит, что в SQL тоже есть циклы...

Дело обстоит примерно так.

Существует классический SQL, в котором создается запрос и получается результат (ответ на запрос). С точки зрения наблюдателя (программиста) запрос это некий текст на формальном языке, который, будучи (каким-то образом, сейчас неважно каким) отправленным на выполнение, возвращает плоский набор данных (таблицу).

Для СУБД, которая выполняет запрос, его текст является командой. В процессе ее исполнения СУБД сама, незаметно для нас, осуществляет и циклы, и промежуточные хранения данных, и сортировку по Кнуту методом какого-нибудь пузырька и еще кучу всяких добрых дел. Мы от всего этого абстрагированы, просто в это время сидим, курим бамбук и ждём ответа на свой вопрос-запрос.

Не будь SQLя, мы бы все эти циклы и т.п. писали бы САМИ, как писали когда-то в эпоху Клиппера и первых версий dBase (если не еще "хуже", в смысле более подробно без специальных команд работы с данными).

И хотя "одним запросом" (а они могут быть невероятно сложные - у меня в Oracle бывали под 60K текста), можно сделать многое, но далеко не всё. К тому же, с увеличением сложности запроса затраты на его сопровождение возрастают в квадрате (говорю по собственному опыту).

С целью преодоления этих трудностей и были разработаны процедурные расширения SQL - специальные языки программирования, способные связать операции над множествами с обычными процедурными ("шаг за шагом") элементами программирования (циклами, условиями и т.п.), например, язык PL/SQL в Oracle или Transact-SQL в MS SQL Server.

А для неспецифических языков, например, для нашего любимого VBA, стали разрабатывать специальные библиотеки типа DAO или ADO. Поэтому на VBA мы теперь можем решать вполне SQL-ные задачи не хуже, чем на Transact-SQL.

Автор - Gustav
Дата добавления - 08.04.2013 в 13:25
nerv Дата: Понедельник, 08.04.2013, 14:35 | Сообщение № 14
Группа: Редакторы
Ранг: Обитатель
Сообщений: 431
Репутация: 193 ±
Замечаний: 0% ±

Gustav, форум не дает пока репутацию изменить. В любом случае спасибо smile

Цитата (Gustav)
В процессе ее исполнения СУБД сама, незаметно для нас, осуществляет и циклы, и промежуточные хранения данных, и сортировку по Кнуту методом какого-нибудь пузырька и еще кучу всяких добрых дел

это понятно )

вся прелесть в том, что
Цитата (Gustav)
Мы от всего этого абстрагированы, просто в это время сидим, курим бамбук и ждём ответа на свой вопрос-запрос

именно поэтому мне интересен SQL smile Я и класс для себя (и всех желающих) запилил, чтобы проще было работать (абстрагироваться от создать объект connection, соединиться, разъединиться и т.п.)

Цитата (Gustav)
Не будь SQLя, мы бы все эти циклы и т.п. писали бы САМИ

согласен. За себя скажу: достаточно много задач приходится решать с "массивами данных". Многие из них сводятся к "элементарным" операциях с множествами, о кот. я спрашивал выше. Т.о.. вместо того, чтобы писать много кода под каждую задачу, мне (надеюсь) будет проще подключить класс и правильно составить SQL запрос. Также не забываем, что ADO/DAO и еже с ним, позволяет работать с закрытыми(!) книгами, что вдвойне приятно smile

Цитата (Gustav)
И хотя "одним запросом" можно сделать многое, но далеко не всё. К тому же, с увеличением сложности запроса затраты на его сопровождение возрастают в квадрате.

Верю smile Поэтому, по возможности стараюсь решать задачи поэтапно: запрос - результат (выгрузка на лист). Запрос к результату выгрузки. В большинстве случаев это допустимо. Кроме того, с помощью упомянутого мною ранее класса это довольно просто и понятно выглядит (как мне кажется).

Цитата (Gustav)
или Transact-SQL в MS SQL Server

ага, я его вчера загугливал smile

И все-таки хотелось бы увидеть пример (желательно простой) и решение задачи , где могут потребоваться циклы в SQL.

Думаю, немного позднее создам тему: "Задачи и решения" применительно к SQL в Эксель.


Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


YM 41001156540584 / WM WMR R21924176233

https://github.com/nervgh/vba
 
Ответить
СообщениеGustav, форум не дает пока репутацию изменить. В любом случае спасибо smile

Цитата (Gustav)
В процессе ее исполнения СУБД сама, незаметно для нас, осуществляет и циклы, и промежуточные хранения данных, и сортировку по Кнуту методом какого-нибудь пузырька и еще кучу всяких добрых дел

это понятно )

вся прелесть в том, что
Цитата (Gustav)
Мы от всего этого абстрагированы, просто в это время сидим, курим бамбук и ждём ответа на свой вопрос-запрос

именно поэтому мне интересен SQL smile Я и класс для себя (и всех желающих) запилил, чтобы проще было работать (абстрагироваться от создать объект connection, соединиться, разъединиться и т.п.)

Цитата (Gustav)
Не будь SQLя, мы бы все эти циклы и т.п. писали бы САМИ

согласен. За себя скажу: достаточно много задач приходится решать с "массивами данных". Многие из них сводятся к "элементарным" операциях с множествами, о кот. я спрашивал выше. Т.о.. вместо того, чтобы писать много кода под каждую задачу, мне (надеюсь) будет проще подключить класс и правильно составить SQL запрос. Также не забываем, что ADO/DAO и еже с ним, позволяет работать с закрытыми(!) книгами, что вдвойне приятно smile

Цитата (Gustav)
И хотя "одним запросом" можно сделать многое, но далеко не всё. К тому же, с увеличением сложности запроса затраты на его сопровождение возрастают в квадрате.

Верю smile Поэтому, по возможности стараюсь решать задачи поэтапно: запрос - результат (выгрузка на лист). Запрос к результату выгрузки. В большинстве случаев это допустимо. Кроме того, с помощью упомянутого мною ранее класса это довольно просто и понятно выглядит (как мне кажется).

Цитата (Gustav)
или Transact-SQL в MS SQL Server

ага, я его вчера загугливал smile

И все-таки хотелось бы увидеть пример (желательно простой) и решение задачи , где могут потребоваться циклы в SQL.

Думаю, немного позднее создам тему: "Задачи и решения" применительно к SQL в Эксель.

Автор - nerv
Дата добавления - 08.04.2013 в 14:35
LightZ Дата: Понедельник, 08.04.2013, 14:40 | Сообщение № 15
Группа: Авторы
Ранг: Форумчанин
Сообщений: 120
Репутация: 48 ±
Замечаний: 0% ±

Может кого-то заинтересует ссылочка на эту тему: http://support.microsoft.com/kb/257819/ru
И еще есть файл-справка по ADO (для vba) - если кому-то интересно, могу скинуть (спасибо Р Дмитрию за файл) smile


E-mail: overseerpower@gmail.com
Skype: Bogdan_Rud
WMR: R166238237296
 
Ответить
СообщениеМожет кого-то заинтересует ссылочка на эту тему: http://support.microsoft.com/kb/257819/ru
И еще есть файл-справка по ADO (для vba) - если кому-то интересно, могу скинуть (спасибо Р Дмитрию за файл) smile

Автор - LightZ
Дата добавления - 08.04.2013 в 14:40
nerv Дата: Понедельник, 08.04.2013, 14:45 | Сообщение № 16
Группа: Редакторы
Ранг: Обитатель
Сообщений: 431
Репутация: 193 ±
Замечаний: 0% ±

Цитата (LightZ)
Может кого-то заинтересует

эта и не только ссылки есть в модуле класса в этой теме http://www.excelworld.ru/forum/3-4357-1. Если хочешь, могу их в пост темы добавить.


Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


YM 41001156540584 / WM WMR R21924176233

https://github.com/nervgh/vba


Сообщение отредактировал nerv - Понедельник, 08.04.2013, 14:45
 
Ответить
Сообщение
Цитата (LightZ)
Может кого-то заинтересует

эта и не только ссылки есть в модуле класса в этой теме http://www.excelworld.ru/forum/3-4357-1. Если хочешь, могу их в пост темы добавить.

Автор - nerv
Дата добавления - 08.04.2013 в 14:45
Johny Дата: Понедельник, 08.04.2013, 14:48 | Сообщение № 17
Группа: Друзья
Ранг: Новичок
Сообщений: 14
Репутация: 13 ±
Замечаний: 0% ±

2013
Саша, почитай эту статью про jetSQL. Именно эта версия SQL используется в запрос в Экселе.


There is no knowledge that is not power
 
Ответить
СообщениеСаша, почитай эту статью про jetSQL. Именно эта версия SQL используется в запрос в Экселе.

Автор - Johny
Дата добавления - 08.04.2013 в 14:48
Gustav Дата: Понедельник, 08.04.2013, 16:54 | Сообщение № 18
Группа: Админы
Ранг: Участник клуба
Сообщений: 2808
Репутация: 1183 ±
Замечаний: ±

начинал с Excel 4.0, видел 2.1
В Jet SQL мне нравится возможность последующего использования в одной строке результатов уже выполненных вычислений в этой же строке, т.е. практически как формулы в самом Excel. В явном виде описания этой фичи в документации я не встречал.

Чтобы было понятно о чём я, приведу такой пример, возвращающий в E1:G1 три значения 10, 15 и 25:
[vba]
Код
Sub Example2()
     Dim ADO As New ADO
      
     ADO.Query "SELECT a, a + 5 AS d, a + d AS e FROM " & _
               "(" & _
               "SELECT 10 AS a, 20 AS b, 30 AS c FROM [Лист1$A1:A1]" & _
               ")"
      
     Range("E1").CopyFromRecordset ADO.Recordset  
     ADO.Disconnect
End Sub
[/vba]

А вот "большой взрослый" Oracle аналогичный запрос не выполнит:
[vba]
Код
SELECT a, a + 5 AS d, a + d AS e FROM
(  
SELECT 10 AS a, 20 AS b, 30 AS c FROM dual
)
[/vba]

А выполнит только вот такой, когда вычисление d выполняется на промежуточном этапе:
[vba]
Код
SELECT a, d, a + d AS e FROM  
(
SELECT a, a + 5 AS d FROM
(  
SELECT 10 AS a, 20 AS b, 30 AS c FROM dual
))
[/vba]


МОИ: Ник, Tip box: 41001663842605
 
Ответить
СообщениеВ Jet SQL мне нравится возможность последующего использования в одной строке результатов уже выполненных вычислений в этой же строке, т.е. практически как формулы в самом Excel. В явном виде описания этой фичи в документации я не встречал.

Чтобы было понятно о чём я, приведу такой пример, возвращающий в E1:G1 три значения 10, 15 и 25:
[vba]
Код
Sub Example2()
     Dim ADO As New ADO
      
     ADO.Query "SELECT a, a + 5 AS d, a + d AS e FROM " & _
               "(" & _
               "SELECT 10 AS a, 20 AS b, 30 AS c FROM [Лист1$A1:A1]" & _
               ")"
      
     Range("E1").CopyFromRecordset ADO.Recordset  
     ADO.Disconnect
End Sub
[/vba]

А вот "большой взрослый" Oracle аналогичный запрос не выполнит:
[vba]
Код
SELECT a, a + 5 AS d, a + d AS e FROM
(  
SELECT 10 AS a, 20 AS b, 30 AS c FROM dual
)
[/vba]

А выполнит только вот такой, когда вычисление d выполняется на промежуточном этапе:
[vba]
Код
SELECT a, d, a + d AS e FROM  
(
SELECT a, a + 5 AS d FROM
(  
SELECT 10 AS a, 20 AS b, 30 AS c FROM dual
))
[/vba]

Автор - Gustav
Дата добавления - 08.04.2013 в 16:54
LightZ Дата: Понедельник, 08.04.2013, 18:03 | Сообщение № 19
Группа: Авторы
Ранг: Форумчанин
Сообщений: 120
Репутация: 48 ±
Замечаний: 0% ±

Еще интересный момент - в sql запросах через ADO можно использовать VBA функции, например: [vba]
Код
"SELECT * FROM data WHERE left(id,1)=9"
[/vba]


E-mail: overseerpower@gmail.com
Skype: Bogdan_Rud
WMR: R166238237296
 
Ответить
СообщениеЕще интересный момент - в sql запросах через ADO можно использовать VBA функции, например: [vba]
Код
"SELECT * FROM data WHERE left(id,1)=9"
[/vba]

Автор - LightZ
Дата добавления - 08.04.2013 в 18:03
nerv Дата: Вторник, 09.04.2013, 17:55 | Сообщение № 20
Группа: Редакторы
Ранг: Обитатель
Сообщений: 431
Репутация: 193 ±
Замечаний: 0% ±

Цитата (LightZ)
Еще интересный момент - в sql запросах через ADO можно использовать VBA функции

ага, я знаю smile Мне Johny, говорил.

Цитата (Gustav)
В Jet SQL мне нравится возможность последующего использования в одной строке результатов уже выполненных вычислений в этой же строке

спасибо, интересно

Johny, спасибо.


Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


YM 41001156540584 / WM WMR R21924176233

https://github.com/nervgh/vba
 
Ответить
Сообщение
Цитата (LightZ)
Еще интересный момент - в sql запросах через ADO можно использовать VBA функции

ага, я знаю smile Мне Johny, говорил.

Цитата (Gustav)
В Jet SQL мне нравится возможность последующего использования в одной строке результатов уже выполненных вычислений в этой же строке

спасибо, интересно

Johny, спасибо.

Автор - nerv
Дата добавления - 09.04.2013 в 17:55
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!