【发布时间】:2011-01-02 04:21:21
【问题描述】:
我的平台:
PHP 和 mySQL
我有什么:
我有 4 个表,即“books”、“book_type”、“book_categories”、“all_categories”。
我想做什么:
简单来说,我想显示所有有库存的书籍,即 in_stock = 'y',以及所有表格中的所有书籍相关信息,只显示一次而不重复条目。目前每本书都在重复,我只想展示一次。
当前问题:
在我的应用程序的前端,条目会重复显示,而实际上我希望它们只显示一次(如在 DISTINCT / UNIQUE 中)并且不会重复。
我的怀疑:
我怀疑重复数据是因为每本书所属的类别。每本书条目都会显示多次,因为它属于一个类别。令人困惑?我的意思是,如果 book1 属于 4 个类别,则 book1 显示 4 次。如果 book2 属于 2 个类别,则显示 2 次。
我需要什么:
我需要能够解决上述问题的 PHP 和 mySQL 代码。我希望我们可以在不使用 mySQL 中的 GROUP_CONCAT 的情况下解决问题,因为同样有一个限制(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
在此先感谢大家。
【问题讨论】:
-
请注意我对您的 100 查询备注所做的修改。
-
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 WHERE books.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');
-
@MindStalker 谢谢。