Классический пример выражения для выбора без соединения, которое возвращает декартово произведение всех результатов комбинирования перечисленных таблиц.
SQL Database Solution
Просто импортируйте Animals, Fruit, Country в виде отдельных таблиц в любую базу данных SQL, такую как MS Access, SQLite, MySQL и т. д. и таблицы таблиц без объединений, включая неявные (WHERE
) и явные (JOIN
) объединяются:
SELECT Animals.Animal, Fruits.Fruit, Countries.Country
FROM Animals, Countries, Fruits;
Excel Solution
То же понятие с запуском non-join SQL statement в VBA с использованием ODBC-соединения с книгой, содержащей диапазоны «Животные, страны и фрукты». Например, каждая группа данных находится в своем собственном листе с таким же именем.
Sub CrossJoinQuery()
Dim conn As Object
Dim rst As Object
Dim sConn As String, strSQL As String
Set conn = CreateObject("ADODB.Connection")
Set rst = CreateObject("ADODB.Recordset")
sConn = "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" _
& "DBQ=C:\Path To\Excel\Workbook.xlsx;"
conn.Open sConn
strSQL = "SELECT * FROM [Animals$A1:A3], [Fruits$A1:A3], [Countries$A1:A3] "
rst.Open strSQL, conn
Range("A1").CopyFromRecordset rst
rst.Close
conn.Close
Set rst = Nothing
Set conn = Nothing
End Sub
Вы действительно должны посмотреть на Нормализация базы данных и сначала нормализовать свою структуру, добавив таблицу переходов и удерживая отношение из таблицы, каждое отношение, хранящееся в таблице c, будет храниться в новой таблице соединений, но не разделено запятыми список каждой строки будет содержать идентификатор c и один идентификатор пользователя для каждой строки, если вы не можете изменить свою схему, вы можете использовать find_in_set
для поиска значений в наборе
select *
from tblC c
JOIN tblB b
ON (find_in_set(b.userid,c.userids) > 0)
where c.nname="new1"
Редактировать для нормализации схемы
Я удалил столбец userids
из вашего tblC
, и вместо этого я создал новую таблицу соединений как tblC_user
с 2 столбца c_id
это будет связано с столбцом id tblC
и вторым userid
, чтобы хранить пользовательские отношения пользователей для tblC
, см. Примерную схему для tblC
CREATE TABLE if not exists tblC
(
id int(11) NOT NULL auto_increment ,
nname varchar(255),
PRIMARY KEY (id)
);
INSERT INTO tblC (id, nname) VALUES
('1', 'new1'),
('2', 'new2'),
('3', 'new3'),
('4', 'new4'),
('5', 'new5');
И здесь ваша таблица соединений как tblC_user
CREATE TABLE if not exists tblC_user
(
c_id int,
userid int
);
INSERT INTO tblC_user (c_id,userid) VALUES
('1','1'),
('1','2'),
('2','1'),
('2','3'),
('3','1'),
('3','4'),
('4','3'),
('4','2'),
('5','5'),
('5','2');
В приведенном выше примере, если вы заметили, что я не сохранял никаких разделенных запятыми отношений, каждое отношение пользователя для tblC
сохраняется в новой строке, set Я использовал таблицу соединений в join, и новый запрос будет похож на belo w
select *
from tblC c
join tblC_user cu on(c.id = cu.c_id)
join tblB b on (b.userid = cu.userid)
where c.nname="new1"
Теперь над запросом можно оптимизировать, используя индексы, вы можете легко поддерживать каскадные отношения