[MySQL-гуру] Сложный запрос к базе

Статус
В этой теме нельзя размещать новые ответы.

DOLARiON

Гуру форума
Регистрация
4 Сен 2006
Сообщения
191
Реакции
65
итак есть огромная база с примерно такими таблицами:

Table `Group` {
id,
user,
param1_i,
param1,
param2_i,
param2,
...
param9_i,
param9
} - все поля числовые
~порядка 50 000 000 записей

соответственно каждое поле в таблице соответствует ID в другой таблице, где и лежат уже все необходимые данные

т.е.:

Table `Group` {
id, --> порядковый номер записи (набор параметров)
user, --> ID юзера -> таблица users

~
до этого момента все просто
LEFT JOIN `users` и полетели

...а вот дальше как быть:
~

param1_i, --> ID базы с данными... к примеру если param1_i == 1, то база с параметрами param_aa, если param1_i == 2, то база с параметрами param_ab... и т.д.
param1, --> соответственно, если param1_i == 1, то делаем лефт джоин таблички param_aa
param2_i, --> следующий параметр базы (к примеру == 10)
param2, --> соответственно выбираем из базы param_XX (последние 2 бкуы базы на основе param2_i), где param_XX.ID == param2
...
ну и т.д.

соответственно, за один присест (запрос) может быть до 10 инклюдов базы
}

соответственно, у меня есть изначальная разлиновка... какой параметр таблицы (paramX_i) соответствует какая таблица param_XX - тут все банально:
id - table
1 - aa
2 - ab
3 - ac
4 - ad
...
и т.д.
до zz
итого 676...

уважаемые Знатоки, а теперь внимание вопрос :)

как динамично подставлять таблицу?!
т.е.
у меня запрос
SELECT *
from `Group`
where `user`
LIMIT 10

соответственно сюда добавляем ЛЕФТ ДЖОИН users -> получаем инфу о юзере,

нужно так же подставлять
базу под каждый param и получать из нее данные одним запросом

PS. я вот тут подумал... может процедурами сделать?! ......правда ни разу их не юзал :nezn:
 
Сначала из-за наличия путанных выражений с участием слов "база", "таблица" ничерта не понял, разобрался что ты приблизительно хочешь только после боевых "стограммов" и повторного прочтения.
сначала думал поможет банальный IF-ELSE? поняв масштаб задумманого остается только вариант с динамическим SQL, собирается строка с SQL-запросом и запускается оператором EXECUTE. Читай хелп, сам юзал один единственный раз и то случайно :) потом ушел от него переделав конструкцию работы приложения.
вот и примерчик

-- Execute the SELECT statement.
declare @test varchar(30)
set @test = 'select * from test'
execute(@test)

еще пример
SET @s = CONCAT('SELECT * FROM authors WHERE id BETWEEN ', _min, ' AND ', _max);
PREPARE stmt1 FROM @s;
EXECUTE stmt1;

и еще пример

SET @s = 'SELECT * FROM authors WHERE id BETWEEN ? AND ?';
SET @min = _min;
SET @max = _max;

PREPARE stmt1 FROM @s;
EXECUTE stmt1 USING @min, @max;
DEALLOCATE PREPARE stmt1;

надеюсь поможет.
 
param1_i, --> ID базы с данными... к примеру если param1_i == 1, то база с параметрами param_aa, если param1_i == 2, то база с параметрами param_ab... и т.д.
param1, --> соответственно, если param1_i == 1, то делаем лефт джоин таблички param_aa
param2_i, --> следующий параметр базы (к примеру == 10)
param2, --> соответственно выбираем из базы param_XX (последние 2 бкуы базы на основе param2_i), где param_XX.ID == param2
...

нужно так же подставлять
базу под каждый param и получать из нее данные одним запросом.....
Какая то каша сплошная, определись, где у тебя база, а где таблица, и какой вывод хочешь получить в итоге. :)
 
ё!
короче,
есть таблицы:

Table `Group` {
id,
user,
param1_i,
param1,
param2_i,
param2,
...
param9_i,
param9

}

Table `user` {
id,
name

}

Table `param_aa` {
id,
name

}

Table `param_ab` {
id,
name

}

Table `param_ac` {
id,
name

}
и т.д.
до
Table `param_zz` {
id,
name

}

нужно сделать запрос выборки

SELECT *
FROM `Group`
Where бла-бла-бла


таким образом что

у нас есть два поля
param1_i - идентификатор таблицы из которой нужно брять значение
param1 - id записи из этой самой таблицы

соответственно чтобы вместо поля
param1
подставилось значение из таблицы param_XX с ID == param1,

таблица соответствия
param1_i с названием таблицы выглядит след. образом:

param1_i | table
1 aa
2 ab
...
676 zz

к примеру

если param1_i == 2, param1 == 200, то нам надо
LEFT JOIN `param_ab` где param_ab.id = 200

ну и сопоставить
param1 = param_ab.name

проблема в том что:
в базе хранятся записи в абсолютно разрозненном состоянии, т.е. может быть:

param1_i == 2
param1 == 200

param2_i == 3
param2 == 201

param3_i == 1
param3 == 202

тогда нам надо сделать
LEFT JOIN `param_ab` где param_ab.id = param1 (т.е. = 200)
LEFT JOIN `param_ac` где param_ac.id = param2 (т.е. = 201)
LEFT JOIN `param_aa` где param_aa.id = param3 (т.е. = 202)


вопрос в динамичном подставлении инклюда в процессе выборки

т.е. когда мы выдергиваем 200 записей из таблицы `Group` нужно чтобы КАЖДАЯ выдернтая запись получила свои данные из своей таблицы с param_XX

теперь понятно? :)

----------------------------------------------------

На самом деле
стоит каешна эту таблицу переконвертнуть, но вот вопрос...

какая структура базы выдержит 50КК записей при условии, что данные выглядят след образом:

id - цифра
user - имя + ID в системе - тут понятно

param1 - varchar 255
param2 - varchar 255
...
param9 - varchar 255

причем список этих самых описаний `param` (окурат размещаемых в базах с `param_aa` по `param_zz`) - един... всего ~ 2kk слов и выражений, т.е. можно каешна хранить их в одной большой таблице и делать инклюд ее....но... я себе не представляю поиск по 2кк записям..... или я не прав?!
 
Теперь ясно.
Функции тут могут помочь только отчасти - для определения имени таблицы по ее идентификатору:

CREATE FUNCTION `GETNAME`(tabid INT)
RETURNS varchar(10) CHARSET latin1
BEGIN
DECLARE o1 varchar(10);
SELECT tabname INTO o1 FROM `links` WHERE `idt`=tabid;
RETURN o1;
END;

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

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

имеется база данных Mysql, в этой базе данных установлен WP.
теперь мне надо выполнить нужный запрос для этой Mysql базы.
проблема в чём. вкладку "выполнить запрос" в панеле PhpMyadmin я вижу. а дальше тупик.

p.s. сам запрос конечно имеется
 
Теперь ясно.
Функции тут могут помочь только отчасти - для определения имени таблицы по ее идентификатору:...........
Если хотите я сделаю всё одним маленьким SQL запросом, только в данном топике всё запутано, так что либо в ПМ по 3 строки обоих таблиц либо, выкладывайте сюда.
 
Решения зависит от нескольких параметров.
1. Запрос идет из программы: sql-запрос можно составить в тексте программы.
(на времени выполнения не скажется).
2. Запрос жестко забит на сервере SQL - тогда единственный выход написание динамических запросов в процедуре.
3. Частный случай как у тебя - когда в param-таблицах одно поле name:
Select *, dbo.[func_value](param_I,param) as [Твое значение] from group
Далее можешь джонить все что хочешь user,...
Структура таблицы group следующая:
[Group]
ID Int
user Int
param_I int - псевдоним таблицы (1 - param1, 2 - param3,...)
param int - ключ записи в таблице
Текст функции:
Код:
SET QUOTED_IDENTIFIER ON 
GO
SET ANSI_NULLS ON 
GO
CREATE     FUNCTION [dbo].[func_value] (@param Int,@id int)
RETURNS money
AS
BEGIN
  Declare @str varchar(255)
  Set @str = 
	case @param
	when 1 then (select name from param1)
	when 2 then (select name from param3)
	when 3 then (select name from param2) 
	when 4 then (select name from param5)
	when 5 then (select name from param7)
	when 6 then (select name from param4)
RETURN @str
END
GO
SET QUOTED_IDENTIFIER OFF 
GO
SET ANSI_NULLS ON 
GO
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху