[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Выборка количества непустых полей
Страницы: 1, 2
Boolean_Type
Есть таблица, в ней книги и авторы. Сколько авторов добавит пользователь, неизвестно. Нужно вытащить названия тех книг, у которых более трёх авторов.
Есть , конечно, простое решение: добавить доп. поле с количеством авторов каждой книги. Тогда:
SELECT book_name FROM books WHERE count >= 3
Но, предположим, добавление поля count недопустимо. Можно ли как-то составить запрос, который вернёт количество непустых колонок независимо от их количества?
На худой конец можно так:
SELECT book_name FROM books WHERE author_1 !='' AND author_2 !='' AND author_3 !=''
Но это не подходит, если кол-во авторов изменится...

Отмечу, что отношение я составляю сам, так что полям авторов необязательно быть пуст. строкой, можно и NULL. Также можно поменять структуру таблицы. Это на случай, если предлагаемые решения будут радикальными smile.gif
Arh
SELECT `id`,`book_name`,count(`id`) as 'count' FROM books
GROUP BY `author`
HAVING `count` >= 3


_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
Boolean_Type
Цитата (Arh @ 9.11.2014 - 21:23)
SELECT `id`,`book_name`,count(`id`) as 'count' FROM books
GROUP BY `author`
HAVING `count` >= 3


В том-то и дело, что GROUP BY годится для группировки по одному столбцу, а у меня целых три столбца, в каждом из кот-ых - по автору.
В общем, решил делать нормализацию (разбил на 2 отношения) и тогда уже применять GROUP BY.
Спасибо.
Valick
Цитата
В том-то и дело, что GROUP BY годится для группировки по одному столбцу
Boolean_Type
Цитата (Valick @ 9.11.2014 - 22:27)
Цитата
В том-то и дело, что GROUP BY годится для группировки по одному столбцу

нет

???
Вы же сами так и написали -
 GROUP BY `author`
. Группировка лишь по столбцу `author`происходит.
sergeiss
Цитата (Boolean_Type @ 9.11.2014 - 22:08)
В общем, решил делать нормализацию (разбил на 2 отношения) и тогда уже применять GROUP BY.

В данном случае будет наиболее правильным решением. Если, конечно, у тебя именно MySQL, а не PostgreSQL wink.gif В последнем есть тип данных "массив".

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
Invis1ble
Цитата
Вы же сами так и написали

Это не он написал

sergeiss
Привет постгрефил! smile.gif А индекс работает по элементам массива?

_____________

Профессиональная разработка на заказ

Я на GitHub | второй профиль

AllesKlar
Boolean_Type
Естественно, нужно таблицу нормализовать, авторов выностить отдельно, и связующую таблицу делать между книгами и авторами.


_____________
[продано копирайтерам]
Boolean_Type
Цитата (Invis1ble @ 10.11.2014 - 00:57)
Цитата
Вы же сами так и написали

Это не он написал

Да, уже узрел, но всё равно муть написана)

Я создал в итоге 3 отношения ("авторы", "книги" и связующее их по id, с внешними ключами).

Я просто ещё не опытен, поэтому не всегда понимаю, когда нужно, а когда не нужно проводить нормализацию и как ваще лучше сделать. Рука не набита.
Arh
Boolean_Type
Цитата
не всегда понимаю, когда нужно, а когда не нужно проводить нормализацию

Тогда, когда объекты начинают быть не уникальными.

В вашем случае есть 2 объекта - книга и автор.
В одной таблице список авторов и их id
В другой таблице список книг их id и id авторов книги.

От этого и отталкиваетесь.
Если авторов у книги больше одного, нужно еще одну таблицу
| id_книги | id_автора |

Если например нужно поправить имя автора, вы правите всего одну запись, вместо тысячи.
Если нужно добавить книгу автору, добавляете в таблицу с | id_книги | id_автора |
Так же с исправлением/удалением книги.

_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
Boolean_Type
Понял, благодарю.
Есть вопрос, продолжающий тему.
Вот создал я 3 отношения, причём одно из них имеет внешний ключи, ссылающиеся на id 2ух др. таблиц.
Предположим, добавляется новая книга, причём не через phpMyAdmin, а юзером, через приложение. Как обновить таблицы авторов и названий книг, я представляю. Но каким образом обновить данные в отношении с внешними ключами? Запоминать lastInsertId() для запросов к таблицам "книги" и "авторы" и обновить третью таблицу значениями этих двух lastInsertId()? Или есть решение поизящнее?
AllesKlar
Boolean_Type
открыли тразакцию
--- добавили книгу
--- добавили автора книги
--- добавили автора книги
--- .... автора книги
--- добавили в связующую таблицу пары id-книги id-автора (столько пар, сколько авторов)
если все ок -- транзакции коммит
иначе роллбак

Цитата
Я просто ещё не опытен, поэтому не всегда понимаю, когда нужно, а когда не нужно проводить нормализацию

Не нужно понимать, когда нужно нормализовать таблицы.
таблицы нужно нормализовать всегда, минимум в первые три нормальные формы.

Думать нужно лишь о том, нужно ли ДЕнормализовать таблицы, но это уже другая история.
По сути, денормализация - это запись избыточных данных. Бывает нужно, например, для более быстрых выборок. запись будет дольше, но чтение быстрее.
Или, например, обычный заказ в интернет-магазине.
Сделали заказ. Логично предположить, что в таблице заказа будут просто id из таблицы товаров. Ан нет.. завтра на товар цену изменили, а заказ должен остаться по старой цене.
И тут либо вести историю цен по каждому товару, либо денормализовать таблицу Заказ, где, помимо id товара будет присутсвовать его цена.

_____________
[продано копирайтерам]
sergeiss
Цитата (Invis1ble @ 10.11.2014 - 00:57)
Привет постгрефил!  А индекс работает по элементам массива?

Вроде как работает, но с какими-то ограничениями. Поэтому, наверное, лучше не полагаться на эту индексацию.

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
Boolean_Type
Цитата (AllesKlar @ 10.11.2014 - 01:52)
открыли тразакцию
--- добавили книгу
--- добавили автора книги
--- добавили автора книги
--- .... автора книги
--- добавили в связующую таблицу пары id-книги id-автора (столько пар, сколько авторов)
если все ок -- транзакции коммит
иначе роллбак

А как внутри транзакции (по сути - внутри запроса) обратиться к этим самым id книги и id автора? Обычно id автоматически назначаются... Потому и спросил про что-то типа lastInsertId().
AllesKlar
Boolean_Type
Цитата
А как внутри транзакции (по сути - внутри запроса)

почему внутри запроса?
Это отдельные запросы.
1. вставил книгу
2. сохранил ее id что-то типа lastInsertId()
3. вставил автора
4. сохранил id автора что-то типа lastInsertId()
5. вставил автора
6. сохранил id автора что-то типа lastInsertId()
7. вставил автора
8. сохранил id автора что-то типа lastInsertId()
......
в цикле вставил в связывающую таблицу столько строк, сколько авторов для книги

схематично так:
try 
{
$db->transation_start();

$sql = 'INSERT INTO books ....';
$db->query($sql);
$book_id = $db->lastInsertId();

$autor_id = array();

$sql = 'INSERT INTO autor ....';
$db->query($sql);
$autor_id[] = $db->lastInsertId();

$sql = 'INSERT INTO autor ....';
$db->query($sql);
$autor_id[] = $db->lastInsertId();

foreach($autor_id as $a_id)
{
$sql = 'INSERT INTO books_autor (book_id, autor_id) VALUES (' . $book_id . ', ' . $a_id . ')';
$db->query($sql);
}

$db->commit();
}
catch (Exception $e)
{
$db->rollback();
echo 'Exception : ', $e->getMessage(), "\n";
}



_____________
[продано копирайтерам]
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.