Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / MySQL Новый топик    Ответить
 Как сгрупировать данные 2х таблиц, когда из одной нужна одна строка, а из другой все  [new]
Валодя
Member

Откуда:
Сообщений: 9
Доброй ночи
есть запрос

SELECT SQL_CALC_FOUND_ROWS * FROM (SELECT *,
(SELECT users_meta.meta_value FROM users_meta WHERE users_meta.meta_name = 'country' AND users.id = 22 ORDER BY users_meta.id DESC LIMIT 1) AS country,
(SELECT users_meta.meta_value FROM users_meta WHERE users_meta.meta_name = 'address' AND users.id = 22 ORDER BY users_meta.id DESC LIMIT 1) AS address,
(SELECT users_meta.meta_value FROM users_meta WHERE users_meta.meta_name = 'mail_verifikation' AND users.id = 22 ORDER BY users_meta.id DESC LIMIT 1) AS mail_verifikation,
(SELECT users_meta.meta_value FROM users_meta WHERE users_meta.meta_name = 'sms_verifikation' AND users.id = 22 ORDER BY users_meta.id DESC LIMIT 1) AS sms_verifikation                                    
FROM users WHERE id = 22) data


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

SELECT SQL_CALC_FOUND_ROWS * FROM (SELECT *,
(SELECT users_meta.meta_value FROM users_meta ORDER BY users_meta.id DESC LIMIT 1) AS users_meta.meta_name                                    
FROM users WHERE id = 22) data


или есть другой способ получить в одну выборку данные самого юзера и мета полей (хочется большего - получать и users_relationships из которого моно получить родителя и департамент, но до этого далеко)
2 окт 17, 21:50    [20837494]     Ответить | Цитировать Сообщить модератору
 Re: Как сгрупировать данные 2х таблиц, когда из одной нужна одна строка, а из другой все  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 15936
Валодя
есть запрос

Бредовый запрос. Выборка из users_meta никак не зависит от требуемого users.id.
2 окт 17, 23:32    [20837667]     Ответить | Цитировать Сообщить модератору
 Re: Как сгрупировать данные 2х таблиц, когда из одной нужна одна строка, а из другой все  [new]
Валодя
Member

Откуда:
Сообщений: 9
плохо описал
есть юзеры с id и есть меты с user_id (object_id), меты выбираем по user.id = meta.object_id
проблема в том что меты могут дублироваться по meta.meta_name и нужно получить последнюю сортируя по meta.id DESC и беря только последнюю и нужно взять все уникальные - тоесть могут быть записи а могут и не быть meta.meta_name :

страна
последний ip
город
последний ip
город
последний ip

их разное количестко и разное количество дублей

можно так

SELECT id,name,email,pass FROM users WHERE id='$id'

+
SELECT * FROM (SELECT * FROM users_meta WHERE object_id='$id' ORDER BY id DESC) AS data GROUP BY meta_name


но полученные данные нужно обрабатывать и складывать в массив вручную - хочется сразу получить 1 массив вида

array(
	id=>$id,
	name=>$name,
	email=>$email,
	страна=>$country,
	город=>$city,
	последний ip=>$ip
)
3 окт 17, 00:09    [20837701]     Ответить | Цитировать Сообщить модератору
 Re: Как сгрупировать данные 2х таблиц, когда из одной нужна одна строка, а из другой все  [new]
Валодя
Member

Откуда:
Сообщений: 9
Akina,
извиняюсь - запрос в вопросе был такой

SELECT SQL_CALC_FOUND_ROWS * FROM (SELECT *,
(SELECT users_meta.meta_value FROM users_meta WHERE users_meta.meta_name = 'country' AND object_id = 22 ORDER BY users_meta.id DESC LIMIT 1) AS country,
(SELECT users_meta.meta_value FROM users_meta WHERE users_meta.meta_name = 'address' AND object_id = 22 ORDER BY users_meta.id DESC LIMIT 1) AS address,
(SELECT users_meta.meta_value FROM users_meta WHERE users_meta.meta_name = 'mail_verifikation' AND object_id = 22 ORDER BY users_meta.id DESC LIMIT 1) AS mail_verifikation,
(SELECT users_meta.meta_value FROM users_meta WHERE users_meta.meta_name = 'sms_verifikation' AND object_id = 22 ORDER BY users_meta.id DESC LIMIT 1) AS sms_verifikation                                    
FROM users WHERE id = 22) data
3 окт 17, 00:13    [20837707]     Ответить | Цитировать Сообщить модератору
 Re: Как сгрупировать данные 2х таблиц, когда из одной нужна одна строка, а из другой все  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 15936
Стандартный подход - JOIN нескольких копий таблицы с метаданными:

SELECT u.*
     , um1.meta_value country
     , um2.meta_value address
     , um3.meta_value mail_verifikation
     , um4.meta_value sms_verifikation
FROM users u
/* LEFT */ JOIN users_meta um1 ON u.id = um1.object_id AND um1.meta_name = 'country'
/* LEFT */ JOIN users_meta um2 ON u.id = um2.object_id AND um2.meta_name = 'address'
/* LEFT */ JOIN users_meta um3 ON u.id = um3.object_id AND um3.meta_name = 'mail_verifikation'
/* LEFT */ JOIN users_meta um4 ON u.id = um4.object_id AND um4.meta_name = 'sms_verifikation'
WHERE u.id = 22
/* ORDER BY um1.id, um2.id, um3.id, um4.id LIMIT 1 */


Для метаданных, наличие которых гарантируется, используется обычный (INNER) JOIN, для метаданных, которых в таблице может не быть - LEFT JOIN. Сортировка и лимитирование - по вкусу. Опять же только для метаданных, которые могут дублироваться (что в общем странно). Сами необязательные метаданные можно обернуть в COALESCE, чтобы для отсутствующих вместо NULL получать вменяемую текстовку.
3 окт 17, 07:44    [20837840]     Ответить | Цитировать Сообщить модератору
 Re: Как сгрупировать данные 2х таблиц, когда из одной нужна одна строка, а из другой все  [new]
Валодя
Member

Откуда:
Сообщений: 9
Akina,

в том то и дело что мы не знаем есть там данные или нет, поэтому неможем перечислить их тк позже могут появиться новые и нужно каждый раз в запрос будет добавлять новое mena_name

дублирование например ведётся для записи 3х последних ip

в мета я пишу кто создал и когда
3 окт 17, 10:44    [20838225]     Ответить | Цитировать Сообщить модератору
 Re: Как сгрупировать данные 2х таблиц, когда из одной нужна одна строка, а из другой все  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 15936
Валодя
мы не знаем есть там данные или нет, поэтому неможем перечислить их тк позже могут появиться новые и нужно каждый раз в запрос будет добавлять новое mena_name
Тогда динамический SQL.

Хотя разработчик-то знает, чего он напихал в софт, верно? не может же у него клиент отражать параметр, о котором код знать не знает? либо он его точно так же будет отображать динамически... а коли клиенту можно, то и серверу не стыдно.

В любом случае такой подход лучше, чем пачка коррелированных подзапросов. Тебя спасает только то, что в твоём запросе получаются данные исключительно по одному users.id.
3 окт 17, 11:04    [20838308]     Ответить | Цитировать Сообщить модератору
 Re: Как сгрупировать данные 2х таблиц, когда из одной нужна одна строка, а из другой все  [new]
Валодя
Member

Откуда:
Сообщений: 9
Akina, а варианты с while никак не подходят?

SELECT SQL_CALC_FOUND_ROWS * FROM (SELECT *,

while(SELECT * FROM (SELECT * FROM users_meta WHERE object_id='$id' ORDER BY id DESC) AS arr GROUP BY meta_name){ // тут не знаю как получить и пройти по строкам

(SELECT users_meta.meta_value FROM users_meta where id = arr.id) AS arr.meta_name  
 }        
FROM users WHERE id = 22) data


синтаксис вписал от php и показал логику запроса
3 окт 17, 11:27    [20838406]     Ответить | Цитировать Сообщить модератору
 Re: Как сгрупировать данные 2х таблиц, когда из одной нужна одна строка, а из другой все  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 15936
Это и будет динамический SQL на стороне сервера. Читать мануал по PREPARE + EXECUTE + DEALLOCATE, ну и само собой по CREATE PROCEDURE.
3 окт 17, 14:17    [20839043]     Ответить | Цитировать Сообщить модератору
Все форумы / MySQL Ответить