Более короткая версия:
Проверьте выходной столбец lives_together
. Я хочу, чтобы он содержал объединенные (разделенные запятыми) идентификаторы членов, которые живут по тому же адресу, что и текущий член, но не являются родителем или ребенком для него/нее.
Итак, в первой строке, Джон, я хочу идентификатор Мэри (только).
Не Йозеф, так как он - сын Джона, а не Виктория, так как она живет по другому адресу (и она тоже его ребенок).
Сейчас я ничего не получаю, так или иначе это из-за этих строк в запросе (в третьем подзапросе):
mem.id <> m3.parent1 AND
mem.id <> m3.parent2 AND
mem.parent1 <> m3.id AND
mem.parent2 <> m3.id AND
Они должны отфильтровывать всех родителей и детей (что они делают), но по какой-то причине они также отфильтровывают и других членов (Мэри в приведенном выше примере).
Только один этих строк достаточно, чтобы отфильтровать Мэри.
Другим примером является Матс и Габриэлла, они должны получать друг от друга, но они этого не делают.
(Один столбец со всеми людьми living_together
(включая детей) недостаточно, так как я хочу напечатать лиц living_together
перед детьми. Этот вопрос является развитием этот другой вопрос Я спросил некоторое время назад. Одна большая разница в результате, который я хочу, состоит в том, что он никогда не должен группировать людей с разными именами.)
Почему это происходит?
Более длинная версия
У меня есть таблица, members
. Немного упрощенно это выглядит так (вы можете увидеть его целиком в SQLfiddle ниже):
+-------+------------+------------+------------+---------+----------+----------+-----------+-----------+---------------+
| id | first_name | last_name | birthdate | parent1 | parent2 | address | phones | mobiles | emails |
+-------+------------+------------+------------+---------+----------+----------+-----------+-----------+---------------+
| 2490 | Mary | Johansen | 1964-01-24 | NULL | NULL | Street 1 | 1111 | 9999,8888 | [email protected] |
| 2491 | John | Johansen | 1968-01-21 | NULL | NULL | Street 1 | 1111,3333 | 7777 | [email protected] |
| 2422 | Brad | Johansen | 1983-01-07 | 2491 | 2490 | Street 1 | 2222,3333 | 6666 | [email protected] |
| 2493 | Victoria | Andersen | 1982-01-14 | 2490 | 2491 | Av. 2 | 4444 | 5555 | [email protected] |
+-------+------------+------------+------------+---------+----------+----------+-----------+-----------+---------------+
Мэри и Джон женаты, с двумя детьми; Йозеф и Виктория. Виктория ушла.
Я хочу напечатать список адресов, который группирует тех, кто живет по тому же адресу. Итак, Мэри, Джон и Йозеф должны сгруппироваться, но Виктория должна получить отдельную информацию. Дети должны быть напечатаны после супругов (и любых других членов, проживающих по этому адресу), это причина их извлечения отдельно.
Вот как выглядит моя база данных и весь мой запрос:
http://sqlfiddle.com/#!2/1f87c4/2 это похоже на фактические данные, таблица содержит около 400 строк.
Итак, я хочу, чтобы столбец вывода lives_together
содержал group_concat
inated IDs совпадающих элементов. Поэтому я должен получить John id
в столбце Mary lives_together
, и наоборот. И не дети иды.
Я ожидаю что-то похожее на следующее.
Обратите внимание, что Брэд показан после Джона, несмотря на то, что у него как младший id, так и имя, начинающееся с буквы раньше в алфавите, это потому, что он ребенок в семье. Дети должны быть отсортированы по дате рождения (вы можете увидеть эту колонку в разделе "Также обратите внимание, что их номера телефонов добавляются вместе с их фамилией, но их мобильные номера (и электронные письма) помещаются с именами
+----------------------------------------------------
| Andersen Av 2 4444
| Victoria 5555 [email protected]
+----------------------------------------------------
| Johansen Street 1 1111,2222,3333
| John 7777 [email protected]
| Mary 9999,8888 [email protected]
| Brad 6666 [email protected]
+----------------------------------------------------
Это, однако, не то, что я ожидаю от запроса ниже, но моя цель после некоторой обработки PHP.
Это то, что я хочу из запроса:
+------+----------+-----------+------------+----------+-----------+-----------+---------------+-----------+-----------+----------------+
| id | lname | fname | birthdate | address | phones | mobiles | emails | parents | children | lives_together |
+------+----------+-----------+------------+----------+-----------+-----------+---------------+-----------+-----------+----------------+
| 2490 | Johansen | Mary | 1964-01-24 | Street 1 | 1111 | 9999,8888 | [email protected] | NULL | 2424 | 2491 |
+------+----------+-----------+------------+----------+-----------+-----------+---------------+-----------+-----------+----------------+
| 2491 | Johansen | John | 1968-01-21 | Street 1 | 1111,3333 | 7777 | [email protected] | NULL | 2424 | 2490 |
+------+----------+-----------+------------+----------+-----------+-----------+---------------+-----------+-----------+----------------+
| 2422 | Johansen | Brad | 1983-01-07 | Street 1 | 2222,3333 | 6666 | [email protected] | 2490,2491 | NULL | NULL |
+------+----------+-----------+------------+----------+-----------+-----------+---------------+-----------+-----------+----------------+
| 2493 | Andersen | Victoria | 1982-01-14 | Av. 2 | 4444 | 5555 | [email protected] | NULL | NULL | NULL |
+------+----------+-----------+------------+----------+-----------+-----------+---------------+-----------+-----------+----------------+
Здесь мой запрос (также несколько упрощен):
SELECT
mem.id as id,
mem.last_name as lname,
mem.first_name as fname,
mem.birthdate as birthdate,
mem.address as address,
mem.phones as phones,
mem.mobiles as mobiles
(SELECT
GROUP_CONCAT(m1.id)
FROM
members m1
WHERE
(mem.parent1 = m1.id OR mem.parent2 = m1.id) AND
LOWER(REPLACE(mem.last_name, ' ', '')) = LOWER(REPLACE(m1.last_name, ' ', '')) AND
LOWER(REPLACE(mem.address, ' ', '')) = LOWER(REPLACE(m1.address, ' ', '')) AND
mem.id <> m1.id
) as parents,
(SELECT
GROUP_CONCAT(m2.id)
FROM
members m2
WHERE
(mem.id = m2.parent1 OR mem.id = m2.parent2) AND
LOWER(REPLACE(mem.last_name, ' ', '')) = LOWER(REPLACE(m2.last_name, ' ', '')) AND
LOWER(REPLACE(mem.address, ' ', '')) = LOWER(REPLACE(m2.address, ' ', '')) AND
mem.id <> m2.id
) as children,
(SELECT
GROUP_CONCAT(m3.id)
FROM
members m3
WHERE
mem.id <> m3.parent1 AND
mem.id <> m3.parent2 AND
mem.parent1 <> m3.id AND
mem.parent2 <> m3.id AND
LOWER(REPLACE(mem.last_name, ' ', '')) = LOWER(REPLACE(m3.last_name, ' ', '')) AND
LOWER(REPLACE(mem.address, ' ', '')) = LOWER(REPLACE(m3.address, ' ', '')) AND
mem.id <> m3.id
) as lives_together
FROM
members mem
ORDER BY
mem.last_name ASC,
mem.first_name ASC
Когда запрос находится в Марии и проходит третий подзапрос (lives_together
), он должен получить Джона, но не Йозефа или Викторию.
Не Йозеф из-за mem.parent2 <> m3.id
, а не Виктория из-за LOWER(REPLACE(mem.address, ' ', '')) = LOWER(REPLACE(m3.address, ' ', ''))
.
Это работает, но по какой-то причине у Джона тоже нет, я просто получаю NULL
.
Я получаю как Джон, Йозеф, так и Викторию, если я удалю эту часть:
mem.id <> m3.parent1 AND
mem.id <> m3.parent2 AND
mem.parent1 <> m3.id AND
mem.parent2 <> m3.id AND
Но когда он там, я не получаю ни одного из них. Я не понимаю, почему эта часть отфильтровывает и Джона. (Обратите внимание, что эти строки вообще не упрощаются). Только один из них для строк отфильтровывает Джона, но работает как ожидалось для Йозефа.
Что-то не так с моим кодом?