PHP & mySQL: Повторение проблемы записей - Потребность каждая запись для разоблачения только однажды, но они повторяются

МОЯ ПЛАТФОРМА:

PHP & mySQL

ЧТО Я ИМЕЮ ЗДЕСЬ:

У меня есть 4 таблицы, а именно, 'книги', 'book_type', 'book_categories', all_categories'.

ЧТО Я ПЫТАЮСЬ СДЕЛАТЬ:

В простых словах я хочу отобразить все книги, которые находятся в запасе т.е. in_stock = 'y', со всей книжной сопутствующей информацией от всех таблиц, только однажды, не повторяя записи. В настоящее время каждая из книг повторяется, и я хочу показать им только однажды.

ТЕКУЩАЯ ПРОБЛЕМА:

В frontend в рамках моего приложения., записи показывают неоднократно, когда на самом деле, когда я ожидаю, что они обнаружатся только однажды (как в ОТЛИЧНОМ / УНИКАЛЬНЫЙ) и не повторят себя.

МОЕ ПОДОЗРЕНИЕ:

Я подозреваю, что повторяющиеся данные из-за категорий, которым принадлежит каждая из книг. Каждую запись по счету показывают так много раз, как она принадлежит категории. Путание? Я подразумеваю что, если book1 принадлежит 4 категориям, то book1 показывают 4 раза. Если book2 принадлежат 2 категориям, то это показывают 2 раза.

В ЧЕМ Я НУЖДАЮСЬ:

Мне нужен код PHP & mySQL, который решил бы вышеупомянутую проблему. Я надеюсь, что мы можем решить проблему, не используя GROUP_CONCAT в MySQL, поскольку существует предел (1024?) для того же. Книга может принадлежать многим категориям, и я не хочу рисковать терять любые данные при помощи GROUP_CONCAT. Я также хотел бы сделать это в едином запросе, не получая доступ к базе данных неоднократно в цикле. Спасибо за понимание.

Все таблицы и соответствующие данные для тиражирования проблемы следующие:

CREATE TABLE IF NOT EXISTS `books` (
  `book_id` int(11) NOT NULL auto_increment,
  `book_type_id` int(11) NOT NULL,
  `book_title` varchar(50) NOT NULL,
  `book_price` smallint(4) NOT NULL,
  `in_stock` char(1) NOT NULL,
  PRIMARY KEY  (`book_id`),
  KEY `book_type_id` (`book_type_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

--
-- Dumping data for table `books`
--

INSERT INTO `books` (`book_id`, `book_type_id`, `book_title`, `book_price`, `in_stock`) VALUES
(1, 1, 'My Book 1', 10, 'y'),
(2, 1, 'My Book 2', 20, 'n'),
(3, 2, 'My Book 3', 30, 'y'),
(4, 3, 'My Book 4', 40, 'y'),
(5, 2, 'My Book 5', 50, 'n'),
(6, 1, 'My Book 6', 60, 'y'),
(7, 3, 'My Book 7', 70, 'n'),
(8, 2, 'My Book 8', 80, 'n'),
(9, 1, 'My Book 9', 90, 'y'),
(10, 3, 'My Book 10', 100, 'n');

--
-- Table structure for table `book_type`
--

CREATE TABLE IF NOT EXISTS `book_type` (
  `book_type_id` int(11) NOT NULL auto_increment,
  `book_type` varchar(50) NOT NULL,
  PRIMARY KEY  (`book_type_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

--
-- Dumping data for table `book_type`
--

INSERT INTO `book_type` (`book_type_id`, `book_type`) VALUES
(1, 'Good'),
(2, 'Better'),
(3, 'Best');


--
-- Table structure for table `book_categories`
--

CREATE TABLE IF NOT EXISTS `book_categories` (
  `book_id` int(11) NOT NULL,
  `cat_id` int(11) NOT NULL,
  PRIMARY KEY  (`book_id`,`cat_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Dumping data for table `book_categories`
--

INSERT INTO `book_categories` (`book_id`, `cat_id`) VALUES
(1, 1),
(1, 2),
(1, 3),
(1, 4),
(1, 5),
(2, 1),
(2, 2),
(3, 1),
(3, 2),
(3, 3);


--
-- Table structure for table `all_categories`
--

CREATE TABLE IF NOT EXISTS `all_categories` (
  `cat_id` int(11) NOT NULL auto_increment,
  `category` varchar(50) NOT NULL,
  PRIMARY KEY  (`cat_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

--
-- Dumping data for table `all_categories`
--

INSERT INTO `all_categories` (`cat_id`, `category`) VALUES
(1, 'Comedy'),
(2, 'Drama'),
(3, 'Romance'),
(4, 'Horror'),
(5, 'Trivia'),
(6, 'Puzzles'),
(7, 'Riddles'),
(8, 'Kids'),
(9, 'Gents'),
(10, 'Ladies');

МОЯ ЦЕЛЬ:

//MY QUERY:
SELECT books.book_title,  books.book_price,
       book_type.book_type,
       all_categories.category
FROM books 
LEFT JOIN book_type       ON books.book_type_id = book_type.book_type_id
LEFT JOIN book_categories ON books.book_id = book_categories.book_id
LEFT JOIN all_categories  ON book_categories.cat_id = all_categories.cat_id
WHERE books.in_stock = 'y' 

ТЕКУЩАЯ ПРОИЗВОДИТЕЛЬНОСТЬ:

book_title  book_price  book_type       category
My Book 1    10          Good            Comedy
My Book 1    10          Good            Drama
My Book 1    10          Good            Romance
My Book 1    10          Good            Horror
My Book 1    10          Good            Trivia
My Book 3    30          Better          Comedy
My Book 3    30          Better          Drama
My Book 3    30          Better          Romance
My Book 4    40          Best            NULL
My Book 6    60          Good            NULL
My Book 9    90          Good            NULL

НУЖЕН СЛЕДУЮЩИЙ ВЫВОД:

book_title  book_price  book_type       category
My Book 1    10          Good            Comedy, Drama, Romance, Horror, Trivia
My Book 3    30          Better          Comedy, Drama, Romance
My Book 4    40          Best            NULL
My Book 6    60          Good            NULL
My Book 9    90          Good            NULL

Благодаря всем заранее.

5
задан Devner 6 January 2010 в 19:01
поделиться

6 ответов

[

] Лучший способ убедиться, что вы не потеряете НИКАКИХ данных - это несколько запросов. Задавайте таблицы по отдельности и присоединяйте их к PHP, вероятно, чтобы ваши запросы выглядели так[

] [
book_id book_title  book_price  book_type         
    1  My Book 1    10          Good           
    2  My Book 3    30          Better          
    3  My Book 4    40          Best           
    4  My Book 6    60          Good            
    5  My Book 9    90          Good           

    book_id, category
    1   Comedy
    1   Drama
    1   Romance
    2   Comedy
] [

]etc[

] [

]Правка:[

] [

]Нет, вам не нужно 100 хитов по БД, только два, один для получения книг, следующий для получения категорий. Петля будет выполнена в PHP для того, чтобы зациклиться на втором запросе и соединить данные с первым. Второй запрос может быть[

] [

]SELECT book.book_id, all_categories.category FROM book_category JOIN all_categories on book_categories.cat_id=all_categories.cat_id JOIN books on books.book_id=book_categories. book_id ГДЕ книги.in_stock= 'y';[

] [

]OR[

] [
SELECT book_categories.book_id, all_categories.category FROM book_category 
JOIN   all_categories on book_categories.cat_id=all_categories.cat_id  
WHERE book_id IN   (SELECT book_id FROM books WHERE books.in_stock= 'y');
]
3
ответ дан 14 December 2019 в 08:52
поделиться

Установите переменную сессии на большое значение, выполните запрос с помощью GROUP_CONCAT, а затем сбросьте ее обратно на глобальное значение .

SET SESSION group_concat_max_len=@@max_allowed_packet;

SELECT books.book_title,  books.book_price,
       book_type.book_type,
       GROUP_CONCAT(all_categories.category)
FROM books 
LEFT JOIN book_type       ON books.book_type_id = book_type.book_type_id
LEFT JOIN book_categories ON books.book_id = book_categories.book_id
LEFT JOIN all_categories  ON book_categories.cat_id = all_categories.cat_id
WHERE books.in_stock = 'y'
GROUP BY books.book_id;

SET SESSION group_concat_max_len=@@group_concat_max_len;
1
ответ дан 14 December 2019 в 08:52
поделиться
[

] Приятель, тебе стоит взглянуть на функцию [] GROUP_CONCAT()[] MySQL. []http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat[][

] [

]Это будет что-то между строк:[

] [
SELECT stuff, GROUP_CONCAT(DISTINCT category ORDER BY category DESC SEPARATOR ', ') 
GROUP BY category, price, book_type
]
1
ответ дан 14 December 2019 в 08:52
поделиться
[

]Можно также использовать сепаратор CONCAT_WS с подзапросом, что-то вроде:[

] [
SELECT  books.book_title, 
    books.book_price, 
    book_type.book_type, 
    CONCAT_WS(', ', (   
                        SELECT  all_categories.category
                          FROM  all_categories 
                         WHERE  all_categories.cat_id = book_categories.cat_id
                     )
             ) AS book_category_list
 FROM books 
LEFT JOIN book_type   
       ON books.book_type_id = book_type.book_type_id                  
LEFT JOIN book_categories 
       ON books.book_id = book_categories.book_id
    WHERE books.in_stock = 'y'
] [

]Извините, форматирование там немного странное.[

].
1
ответ дан 14 December 2019 в 08:52
поделиться

Очень просто. Добавить группу по. Итак, все будет так:

EDIT: Похоже, что лучший способ сделать это - использовать групповой конкат (даже если вас беспокоит его верхний предел), чтобы обойти верхний предел, который у него есть, я бы предложил обновить его во время выполнения. Таким образом, это было бы что-то вроде этого:

SET GLOBAL group_concat_max_len = SOME_BIG_VALUE; #SOME_BIG_VALUE >> 1024

SELECT books.book_title,  books.book_price,
       book_type.book_type,
       GROUP_CONCAT(all_categories.category)
FROM books 
LEFT JOIN book_type       ON books.book_type_id = book_type.book_type_id
LEFT JOIN book_categories ON books.book_id = book_categories.book_id
LEFT JOIN all_categories  ON book_categories.cat_id = all_categories.cat_id
WHERE books.in_stock = 'y'
GROUP BY books.book_title
1
ответ дан 14 December 2019 в 08:52
поделиться

Вы пробовали добавить в выбранное вами отличие?

SELECT DISTINCT books.book_title,  books.book_price,
   book_type.book_type,
   all_categories.category
FROM books 
LEFT JOIN book_type       ON books.book_type_id = book_type.book_type_id
LEFT JOIN book_categories ON books.book_id = book_categories.book_id
LEFT JOIN all_categories  ON book_categories.cat_id = all_categories.cat_id
WHERE books.in_stock = 'y'
GROUP BY books.book_title
0
ответ дан 14 December 2019 в 08:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: