1

Тема: Один запит на вибріку з однієї таблиці двох наборів данних

Як використвуючи один запит функціонально розділений на дві частини в другій частині запиту вибрати дані з цієї ж таблиці (з якої проводилась вибірка в 1-й частині запиту) базуючись на інформації повернутій першою частиною запиту?

2

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Правильно Я Вас розумію - вибрати з вибірки? Тоді це дуже просто - SELECT FROM (SELECT FROM ...) ...

Подякували: koala1

3

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Я не впевнений. Ось є в мене такий запит:

SELECT u.index, u.id AS user_id, u.email, u.parent_id, u.full_name
FROM profile AS u 
WHERE u.index <> 6 OR u.index IS NULL ORDER BY id DESC

А тепер, до того що вже було вибрано, потрібно вибрати ще й full_name тих parent_id які потрапили в першу вибірку. Як таке написати одни запитом?

4

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Invader написав:

Я не впевнений. Ось є в мене такий запит:

SELECT u.index, u.id AS user_id, u.email, u.parent_id, u.full_name
FROM profile AS u 
WHERE u.index <> 6 OR u.index IS NULL ORDER BY id DESC

А тепер, до того що вже було вибрано, потрібно вибрати ще й full_name тих parent_id які потрапили в першу вибірку. Як таке написати одни запитом?

Якщо ви не впевнені навіть після того, як вам підказали правильну (причому разом з тим просту) відповідь, то тоді вам ще зарано з цим розбиратись.

Почніть з чогось більш простого.

5 Востаннє редагувалося ConTrast77 (25.03.2015 23:45:03)

Re: Один запит на вибріку з однієї таблиці двох наборів данних

а у мене проблема така:
SELECT FROM (SELECT FROM ...) ...

Якщо у мене є вкладений запит, але його дані хочу використати потім у загальному зовнішньому запиті, то в мене помилка....
#1146 - Table 'TName1.name1' doesn't exist

SELECT * FROM table1, (SELECT FROM ... name1) as TName1 ...
while table1.NN = TName1.name1


або навіть такий десь запит:
#1146 - Table 'picture.num' doesn't exist

SELECT
      ROUND( RAND()* ((SELECT MAX(`id`) FROM `table1`)-100) )+100  num,
      @num:=@num+1  AS picture
   FROM 
         table1 ss
         left join
         picture
         on `table1`.`id` = picture.num 
   GROUP BY `table1`.`id`

невже немає підходу? при тому що один запит не розуміє дані з інших об'єднаних запитах....
або навіть питання таке: яку сторінку інтернету вивчити для виконання теоретично- задуманого?

6 Востаннє редагувалося volodimirg (26.03.2015 14:59:10)

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Чому так складно. Опрацьовуються запити в скриптах чи в чому? Якщо це в PHP чи в іншій мові, то чому не розбити на окремі запити. Одержати результат одного запиту, з цього запиту вибрати потрібні рядки в скрипті і далі сформувати новий запит ...

7 Востаннє редагувалося ConTrast77 (26.03.2015 15:51:05)

Re: Один запит на вибріку з однієї таблиці двох наборів данних

З вами згоден - і не було би такого питання.  [:}

Але "не пальцем тикано", питання полягає саме в реляційному підході  *DANCE* , бо БД і реляційність - найвища ланка цілісності БД  *YAHOO* . Тобто доки є один цілісний запит - ніхто не може втручатись в вибірки або запис в БД. Це потрібно для цілісності, якщо буде використатись паралельне "сайт-адміністрування", і деякі запити користувачів будуть умовно одночасні до тих самих таблиць.

Це не питання базових знань, з виглядом на "Гавайські острови" очима програмних "костилів".

Подякували: 0xDADA11C71

8

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Це елементарні сабселекти. А ви щось таке понаписували, що страшно.

ви вибірку з 2-х таблиць вмієте робити? от розглядайте внутрішній селект як ще одну таблицю, навіть якщо в ньому вибирається тільки одне поле.

9

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Vo_Vik написав:

Це елементарні сабселекти. А ви щось таке понаписували, що страшно.

ви вибірку з 2-х таблиць вмієте робити? от розглядайте внутрішній селект як ще одну таблицю, навіть якщо в ньому вибирається тільки одне поле.

Це два різні випадки - в випадку з внутрішнім селектом внутрішній селект буде виконуватись стільки разів, скільки записів буде в зовнішньому селекті, що дуже негативно впливає на продуктивність вибірки.

10

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Arete написав:
Vo_Vik написав:

Це елементарні сабселекти. А ви щось таке понаписували, що страшно.

ви вибірку з 2-х таблиць вмієте робити? от розглядайте внутрішній селект як ще одну таблицю, навіть якщо в ньому вибирається тільки одне поле.

Це два різні випадки - в випадку з внутрішнім селектом внутрішній селект буде виконуватись стільки разів, скільки записів буде в зовнішньому селекті, що дуже негативно впливає на продуктивність вибірки.

Залежить як його написати.

11 Востаннє редагувалося ConTrast77 (26.03.2015 21:32:58)

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Як мені докучають відповіді не на задані питання, якщо у самому питанні вже було сказано, що потрібно.
А код наданий як непрацюючий, і вказано чому. Тобто Про сабселект вже було сказано.

Як ви вважаєте, про що я питав?

ConTrast77 написав:

невже немає підходу? при тому що один запит не розуміє дані з інших об'єднаних запитах....
або навіть питання таке: яку сторінку інтернету вивчити для виконання теоретично- задуманого?

наприклад:
- рекурсивність отриманих даних в сабселект чи навпаки
- глобальні змінні для селекту і сабселекту
- глобальні отримані вибірки (рекурсія отриманого поміж сабселектами)
- отримані дані з сабселекту знову вкинути в цей сабселект в частину умови WHERE

12 Востаннє редагувалося Vo_Vik (26.03.2015 21:53:04)

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Взагалі-то, в цій темі в жодному повідомленні не було сказано, що потрібно конкретно.

13

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Приклад працюючого сабселекту.

SELECT AVG(sum_column1)
  FROM (SELECT SUM(column1) AS sum_column1
        FROM t1 GROUP BY column1) AS t1;

14 Востаннє редагувалося ConTrast77 (26.03.2015 22:21:28)

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Vo_Vik написав:

Приклад працюючого сабселекту.

SELECT AVG( sum_column1 )
FROM (

SELECT SUM( column1 ) AS sum_column1
FROM t1
GROUP BY column1
) AS t1;

у мене помилка #1146 - Table 'bd_test.t1' doesn't exist
- сабселект не розуміє таблицю, сгенерованою головною (зовнішньою) відносно себе вибіркою

15 Востаннє редагувалося ConTrast77 (27.03.2015 14:08:20)

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Схоже знайшов рішення своєї проблеми і ТС.
CREATE TEMPORARY TABLES ...

- методом створення тимчасової таблиці, яка не є фізичною, вона автоматично знищується (не обов'язкове ручне керування знищенням таблиці) при закритті сесії користувача. Ця таблиця не є т.з. "віртуальна таблиця" TABLE VIEW.

Вимагає власний тип привілеї для користувача БД:
"Структура" = CREATE TEMPORARY TABLES


- таблиця зберігається у пам'яті і не зберігається в БД на вінчестері (оперативне зберігання)
- реляційність; кожен користувач може створити власну однойменну таку таблицю не заважаючи іншим користувачам (Примітка: таку таблицю можна використати як "костиль" у вигляді глобальної змінної поміж запитами і підзапитами/сабселектами або цілий набір даних. А призначення - тимчасова таблиця)
- якщо ця таблиця створена з однойменною назвою таблиці що вже існує, то вона, собою заслоняє реальну (постійну) таблицю, і робить невидимою, на час "свого існування".
- створення таблиці при копіюваннях даних з SELECT або LIKE стовпчики точно втрачають параметр PRIMARY KEY, але можливо їх створювати по заданих параметрах http://stackoverflow.com/questions/1439 … and-select


CREATE TEMPORARY TABLE tbl_name (...column definitions...);
- створення віртуальної тимчасової таблиці, по заданих параметрах (структури таблиці)

CREATE TEMPORARY TABLE new_table LIKE original_table;
- Повне дублювання заголовків/ структури з іншої таблиці

CREATE TEMPORARY TABLE tbl_name SELECT ... ;
- створення таблиці на умовах готової вибірки / результату набору SELECT ...
- повністю дублює дані в нову створену таблицю, згідно вибірки.
- створює пусту таблицю, по шаблону з SELECT
   (сам перевіряв на MySQL5, книга Пауля збрехала в 3-му виданні, але в 5-му точно так)

    тут помилився, бо якщо запит  в PHPMyAdmin, з наявністю #коментів, тоді якось дивно працює


---
Ця команда - окрема. Логічно вважати, що для реляційності запиту до БД не має необхідності об'єднувати з іншими запитами користувача за сесію.

Приклад:

CREATE TEMPORARY TABLE new_tbl_name SELECT * FROM tbl_name LIMIT 5;
INSERT INTO new_tbl_name SELECT * FROM tbl_name LIMIT 3;
SELECT COUNT(*) FROM new_tbl_name;
...
DROP TEMPORARY TABLE tbl_name;

# не обов'язкове виконання DROP задля видалення тимчасової таблиці з структурою


інформацію взяв за основу тут, в розділі: Creating Temporary Tables (URL)

Подякували: 0xDADA11C7, Invader2

16 Востаннє редагувалося ConTrast77 (27.03.2015 04:04:39)

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Гарний вираз:
- якраз про збереження глобальних змінних, та про область видимості змінних

Рос.:

Прихований текст

хранимые процедуры: DECLARE или SET

зачем вообще нужно DECLARED если можно использовать SET, а можно даже и SET не пользовать, а создавать переменные в контексте выполнения запросов.
и еще насчет области видимости переменных, в доках пишут что видимость ограничена блоком BEGIN END; но и за пределами хранимой процедуры я читаю переменные, которые инициализировались(там же и создавались) внутри процедуры.

http://sqlinfo.ru/forum/viewtopic.php?id=20


Відповідь про змінні користувача в рамках видимості.. запитів
MYSQL: ЗМІННІ В SQL ЗАПИТАХ
http://www.iinuu.ru/ru/it-guru/mysql-po … l-zaprosah


Мабуть команда CASE WHEN ... THEN ... (умова - відповідь)
- вже має закриту видимість умов в області WHEN  від виконання в області THEN
бо WHEN просить дужки відокремлення видимості

SELECT CASE WHEN nn<(@a_tmp:=2) AS dd THEN @a_tmp:=0 END FROM .. ... погано

17

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Давайте тако. Вимкнемо телепатію. Ви даште структуру вашої таблиці(ь) і скажете, що хочете вибрати. А тоді вам спробують дати конкретну відповідь.

18 Востаннє редагувалося ConTrast77 (27.03.2015 22:42:27)

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Добре.
Ось код.

SELECT t.*
FROM
  (SELECT
    ROUND(RAND() * ((SELECT MAX(id) FROM myTable)-100))+100 num,
    @num:=@num+1
  FROM
    (SELECT @num:=0) AS a,
    myTable LIMIT 6) AS b,
    myTable AS t
  WHERE b.num = t.id AND t.xFactor='Q';

Важкість завдання:
Його важкість в тому, що код має вибірку декількох рандомних рядків, тобто умова змінюється кожного разу коли випадає нове число. З новим рандомним числом оновлюється перехід до реально-існуючого стовпчика. і так робить не одну вибірку а декілька разів! тому що умова змінюється в середині одного ЗАПИТУ кожного разу!
Тобто рандом! - не статична вибірка! Оо  *WALL*  , ... її просто так не вкладеш в аби яку частину коду.

Код працює дуже швидко навіть в великих таблицях.
Дійсно шукає випадкові комірки а не підряд "згідно шаблонів"
В таблиці кожен ряд має сортоване/не сортоване значення ID (індексоване, а тому і унікальне)
Значення ID може мати пропуски, а тому вибірка, не знайшовши рядок ID по умові-рандому, виконує новий пошук, доти вихідна таблиця не набере необхідну кількість вибраних рядків.

Проблеми завдання: - з якими я вже зіткнувся, треба вирішувати ...

- не використовувати самий простий запит типу SELECT * FROM myTable ORDER BY RAND() LIMIT 1; , а вдосконалити! наданий вище код (чи пропонувати інший, контрольований умовами коду, не втрачаючи імовірну швидкість пошуку).
- вищевказаний приклад, не перевіряє, якщо рандом випадково двічі обере, один і той самий рядок в вихідну таблицю.
- Чим менше кількість рядків в таблиці пошуку (донору) - тим більше вірогідність що 2 чи 3 рази нам буде показаний однаковий рядок. І тоді фільтрування типу GROUP BY, або SELECT DISTINCT у вищевказаному прикладі! - просто зменшить кількість рядків на виході опісля їх отримання. Ми не виконаємо тоді умову, що нам потрібна "X-кількість" рядків а не "X" мінус фільтр.

Треба:
- кожен рядок рандомно вирахуваний з таблиці
- кожен рядок не однаковий на виході, з аби яким іншим (імовірність однакових полів не повинна трапитись)
- рядків рівно стільки як треба, наприклад 6-ть (шість). І якщо шість у завданні, то не п'ять, не чотири на виході.
- реляційний запит
- таблиця-донор з 500.000 - 1.000.000 рядків. Тобто не можна просто так робити зайві пошукові операції.


Ось тому я поки що теоретично маю вихід:
Використання додаткової тимчасової таблиці CREATE TEMPORARY ...

- коли треба, додам рядок (з перевіркою або без, на однаковість, краще не робити тут перевірку)
- коли треба (якщо треба) порівняю нове отримане рандом-число з тимчасовою таблицею на співпадіння і одночасно перевірка з рядком таблиці-донора


P.S. Може у вас інший варіант чи натяк на методику?
P.P.S. цей текст потім продублюю в свою тему про рандом, затримуюсь ... там ще не виклав деякі результати інших рандом-рішень. Цей приклад буде кінцевим.

19 Востаннє редагувалося Vo_Vik (28.03.2015 00:20:29)

Re: Один запит на вибріку з однієї таблиці двох наборів данних

Вам ніколи не казали що ви тяжкий у спілкуванні? По я з ваших 600 символів тексту, так і не поняв що вам треба) Пробую читати 4-й раз. Навіщо ви перейшли до зминних і тимчасових таблиць, коли прості селекти ще не освоїли. І ще ви розумієте різницю між таблицею, рядком таблиці, полем(колонкою, стовбчиком) таблиці і значенням конкретного поля конкретного рядка таблиці?

SELECT MAX(id) FROM myTable

це є вектор. ви віднімаєте і додаєте 100 до вектора, це може і буде працювати, але нафіга?

 FROM
(SELECT @num:=0) AS a,
myTable LIMIT 6

- як би мало працювати оце. я взагалі не уявляю, навіть не можу уявити логіки, що ви хотіли би щоб воно робило. Це що, щоб нумерувати вибрані рядки?

Важкість завдання:

- бажано дати саме завдання перед тим як пояснювати його важкість. Бо без формалізованого завдання, його реалізувати так нереально.

Треба:

- о тут вже щось пробує вимальовуватись.

Тобто вам треба вибрати з таблиці n унікальних випадкових записів? Десь такої умови я від вас хотів.

20

Re: Один запит на вибріку з однієї таблиці двох наборів данних

З таблиці потрібно вибрати імена, адреси електронної пошти, ідентифікатори, ідентифікатор куратора тих користувачів у яких поле індекс не дорівнює 6 або є NULL. Потім, на основі отриманих даних, вибрати імена кураторів і їхні ідентифікатори. Всі дані зберігається в одній таблиці. Будь-який із користувачів про якого є запис в таблиці може бути куратором для будь-якої к-ті інших користувачів і сам він теж може мати куратора, але тільки одного (якщо це взагалі має якесь значення в контексті даного обговорення). Один запит до однієї таблиці.