Mysql - как отсортировать результаты по значениям в столбцах? - PullRequest
1 голос
/ 07 мая 2020

У меня есть две таблицы базы данных customers, которые содержат данные о клиентах с такой схемой:

mysql> SELECT * FROM customers;

customer_id created_at              partner_id
1           "2019-08-20 09:17:58"   cats
2           "2019-09-12 11:46:37"   dogs

и customers_facts, в которых хранятся факты клиентов в форме fact_name и соответствующих fact_value.

mysql> SELECT * FROM customers_facts;

customer_id fact_name   fact_value
1           name        Milton
1           city        Milan
1           birthday    "2019-08-20 09:17:58"
1           company     Idaho
2           surname     Bloom
2           name        Orlando
3           name        Milton
3           city        Milan
3           birthday    "2011-10-20 11:17:58"
3           company     Chicago

Я хочу создать запрос, чтобы получить все customer_id, где name=Milton и city=Milan отсортированы по birthday и company. Итак, в моем примере результаты будут:

mysql> SELECT customer_id FROM ....

customer_id
1             
3           

У меня есть запрос, который получает все customers_id, где name=Milton и city=Milan

SELECT cf.* FROM customers_facts cf 
WHERE cf.customer_id IN (
SELECT cf.customer_id FROM customers_facts cf
WHERE (cf.fact_name,cf.fact_value) IN (('name','Milton'),('city','Milan'))
GROUP BY cf.customer_id 
HAVING COUNT(*) = 2
)

Но у меня нет идея как отсортировать результаты по fact_value как это сделать? Возможно ли такое при такой схеме?

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Это немного сложно. Вы не можете легко отфильтровать перед агрегированием . Итак, выполните фильтрацию в предложении having:

SELECT customer_id
FROM customers_facts
GROUP BY customer_id 
HAVING SUM( fact_name = 'name' AND fact_value = 'Milton' ) > 0 AND
       SUM( fact_name = 'city' AND fact_value = 'Milan' ) > 0
ORDER BY MAX(CASE WHEN fact_name = 'birthday' THEN fact_value END) DESC,
         MAX(CASE WHEN fact_name = 'company' THEN fact_value END)
0 голосов
/ 07 мая 2020

Используется поворотный лог c, чтобы указать дату рождения для каждой подходящей группы клиентов:

SELECT customer_id
FROM customers_facts
WHERE (fact_name, fact_value) IN (('name', 'Milton'), ('city', 'Milan'))
GROUP BY customer_id 
HAVING MIN(fact_name) <> MAX(fact_name)
ORDER BY MAX(CASE WHEN fact_name = 'birthday' THEN fact_value END);

Помимо предложения ORDER BY, я использовал предложение HAVING, которое гарантирует, что оба совпадающих имя и город присутствовали в каждой подходящей группе клиентов.

Изменить:

Вот желаемое предложение ORDER BY:

ORDER BY
    MAX(CASE WHEN fact_name = 'birthday' THEN fact_value END) DESC,
    MAX(CASE WHEN fact_name = 'company' THEN fact_value END);  -- ASC is default
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...