Cant figure out how to join these tables - sql

Need help with some kind of join here. Cant figure it out.
I want to loop out the forum boards, but I also want to get last_post and last_posterid from posts, and based on last_posterid get username from users.
This is how far I've come yet (:P):
SELECT name, desc, position FROM boards b
INNER JOIN posts p ON ???
INNER JOIN users u ON ???
ORDER BY b.position ASC
Help would be greatly appreciated.
Cheers
CREATE TABLE `posts` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`posterid` int(10) unsigned NOT NULL DEFAULT '0',
`subject` varchar(255) DEFAULT NULL,
`message` text,
`posted` int(10) unsigned NOT NULL DEFAULT '0',
`edited` int(10) unsigned DEFAULT NULL,
`edited_by` int(10) unsigned NOT NULL DEFAULT '0',
`icon` varchar(255) DEFAULT NULL,
`topicid` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
CREATE TABLE `boards` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
`desc` varchar(255) NOT NULL,
`position` int(10) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8
CREATE TABLE `users` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(200) NOT NULL,
`password` varchar(255) NOT NULL,
`salt` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=9 DEFAULT CHARSET=utf8
CREATE TABLE `topics` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`posterid` int(10) unsigned NOT NULL DEFAULT '0',
`subject` varchar(255) NOT NULL,
`posted` int(10) unsigned NOT NULL DEFAULT '0',
`last_post` int(10) unsigned NOT NULL DEFAULT '0',
`last_poster` int(10) unsigned NOT NULL DEFAULT '0',
`num_views` mediumint(8) unsigned NOT NULL DEFAULT '0',
`num_replies` mediumint(8) unsigned NOT NULL DEFAULT '0',
`closed` tinyint(1) NOT NULL DEFAULT '0',
`sticky` tinyint(1) NOT NULL DEFAULT '0',
`icon` varchar(40) DEFAULT NULL,
`boardid` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=16 DEFAULT CHARSET=utf8

Assuming posts.topicid refers to boards.id, and posts.posterid refers to users.id, try something like
SELECT b.name, d.desc, b.position
FROM boards b
LEFT JOIN posts p
ON b.id = p.topicid
LEFT JOIN users u
ON (p.posterid = u.id) AND (p.posted = (SELECT MAX(sp.posted) FROM posts sp GROUP BY))
ORDER BY
b.position ASC
Another remark: try to name your fields such that it is clear what they refer to, for instance:
CREATE TABLE `foo` (
foo_ID UNSIGNED INTEGER NOT NULL AUTO_INCREMENT,
-- more stuff
PRIMARY KEY (`foo_ID`)
);
This allows you to re-use the field name foo_ID in another table, which makes things very easy when performing a join.

Nothing stands out, so this is mostly a guess:
SELECT b.name, b.desc, b.position
FROM boards AS b
INNER JOIN posts AS p
ON b.id = p.topicid
INNER JOIN users AS u
ON p.posterid = u.id
ORDER BY b.position ASC

SELECT username, message, posts.id
FROM users, posts
WHERE posterid=users.id
GROUP BY username, message, posts.id
HAVING posted=MAX(posted)
This might just do to get each user's last post concisely.

Ok, lack of a schema not withstanding, it looks like you could use nested select. Something like:
DECLARE #posts TABLE
(
postdate datetime,
postid int,
boardid int
)
DECLARE #users TABLE
(
userid int,
username varchar(10)
)
DECLARE #boards TABLE
(
boardid int
)
INSERT INTO #boards(boardid) VALUES (1)
INSERT INTO #users (userid, username) values (1, 'Adam')
insert into #posts (postdate, postid, boardid) values (GETDATE(), 1, 1)
SELECT b.*, p.*
from #boards b
inner join
(
SELECT TOP 1 postdate, postid, boardid, username FROM #posts
inner join #users on userid = postid WHERE boardid = 1
order by postdate desc
) as p on p.boardid = b.boardid
Oviously this is heavily generalised and uses some hard-coded values, but hopefully it should give you an option for implementing it on your own tables.
Of course, I infer no correctness in my implementation of the spec - SQL is not my first language lol

Was going to post this as a comment but it was too verbose and messy.
you'll want to use OUTER JOINs because otherwise boards with no posts in them will not show up
any single query that links those four tables is going to be a beast - consider using VIEWs to simplify things
your initial question and the tables you posted leave things a bit ambiguous: do you already have last_post and last_poster filled out in topics? If so, then your primary targets for the join should be boards and topics, and since you're already storing redundant data (I assume for speed?), why don't you also put in a last_post_time or something, which would simplify things a lot and curb load (no need to join in posts at all)?
mediumints? why on Earth? (If you don't need the date, and you think it'll never wrap, I suppose you can use the hack of trusting that a later post will have a higher ID due to autoincrementing key...)

Related

Counting forum topics and replies

I have 2 tables: posts and forum_topics. Each post (a reply) is associated with another post (a forum topic, which is then associated with the forum_topics tables).
Problem: I need to count all forum topics and replies in the posts table. This is what I have so far:
SELECT ForumTopic.id, ForumTopic.title, ForumTopic.modified, COUNT(ReplyLeftOuterJoin.id) as replies_count
FROM forum_topics AS ForumTopic
LEFT OUTER JOIN posts AS PostLeftOuterJoin
ON PostLeftOuterJoin.object_id = ForumTopic.id
AND PostLeftOuterJoin.object_type = 'forum_topic'
AND PostLeftOuterJoin.status = 'approved'
LEFT OUTER JOIN posts AS ReplyLeftOuterJoin
ON ReplyLeftOuterJoin.object_id = PostLeftOuterJoin.id
AND ReplyLeftOuterJoin.object_type = 'post'
AND ReplyLeftOuterJoin.status = 'approved'
WHERE ForumTopic.forum_category_id = 'some_id'
Edit
Currently I'm only getting a count of all replies associated with a forum_topic (post) in the posts table. I would like to get a count of forum_topics in posts table associated with a forum topic in the forum_topics table.
NB FYI, a solution to this problem should use one query only.
Here is the schema of the two tables:
DROP TABLE IF EXISTS `posts`;
CREATE TABLE `posts` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`context_id` bigint(20) unsigned DEFAULT NULL,
`context_type` enum('resource','module','kwik','user','assignment') COLLATE utf8_unicode_ci DEFAULT NULL,
`is_private` tinyint(1) NOT NULL,
`is_unread` tinyint(4) NOT NULL,
`last_replied` datetime NOT NULL,
`object_id` bigint(20) unsigned DEFAULT NULL,
`object_type` enum('forum_topic','forum','user','post') COLLATE utf8_unicode_ci DEFAULT NULL,
`status` enum('approved','unapproved','disabled') COLLATE utf8_unicode_ci NOT NULL,
`post` text COLLATE utf8_unicode_ci NOT NULL,
`user_id` bigint(20) unsigned NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=100 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
DROP TABLE IF EXISTS `forum_topics`;
CREATE TABLE `forum_topics` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`view_count` int(10) unsigned NOT NULL,
`forum_category_id` bigint(20) unsigned NOT NULL,
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
SELECT
ForumTopic.forum_category_id,
COUNT(DISTINCT PostLeftOuterJoin.id) as forumtopics_count,
COUNT(ReplyLeftOuterJoin.id) as replies_count
FROM forum_topics AS ForumTopic
LEFT OUTER JOIN posts AS PostLeftOuterJoin
ON PostLeftOuterJoin.object_id = ForumTopic.id
AND PostLeftOuterJoin.object_type = 'forum_topic'
AND PostLeftOuterJoin.status = 'approved'
LEFT OUTER JOIN posts AS ReplyLeftOuterJoin
ON ReplyLeftOuterJoin.object_id = PostLeftOuterJoin.id
AND ReplyLeftOuterJoin.object_type = 'post'
AND ReplyLeftOuterJoin.status = 'approved'
WHERE ForumTopic.forum_category_id = 'some_id'
GROUP BY
ForumTopic.forum_category_id
;
maybe you can get the result in two queries
the following query will give you the count of posts in each forum
select f.id,f.title,f.modified,Type='Posts',Number=count(*)
from forum_topics as f
inner join posts p on p.forumid=f.id --u used in your query PostLeftOuterJoin.id ( is this the forum id or the posts id ?)
where p.status='approved' and p.object_type='forum_topic'
group by f.id,f.title,f.modified
union
select f.id,f.title,f.modified,Type='Replies',Number=count(*)
from forum_topics as f
inner join posts p on p.forumid=f.id --u used in your query PostLeftOuterJoin.id ( is this the forum id or the posts id ?)
where p.status='approved' and p.object_type='posts'
group by f.id,f.title,f.modified
to distinguish between the posts and replies, i added the Type
and from your application level you can get the forum post count when Type=Posts and same as for the replies
another method
select f.id,f.title,f.modified,Posts=(select count(*) from posts p where f.id=p.object_id and p.status='approved' and p.object_type='forum_topic'),
Replies=(select count(*) from posts p on where f.id=p.object_id
and p.status='approved' and p.object_type='posts')
from forum_topics f
where f.forum_category_id='someid'
hope that this will help you
regards

sql query is returning the same values twice

I have this sql query, and it should be returning two values, which is does but it returns each returned row twice, the sql looks like this,
SELECT * FROM `mailers`
LEFT JOIN `mailer_content` ON `mailers`.`id` = `mailer_content`.`mailer_id`
LEFT JOIN `mailer_images` ON `mailer_content`.`id` = `mailer_images`.`content_id`
WHERE `mailers`.`id` = 26
The table structure for the tables I am query look like this,
-- --------------------------------------------------------
--
-- Table structure for table `mailers`
--
CREATE TABLE `mailers` (
`id` int(11) NOT NULL auto_increment,
`mailer_title` varchar(150) NOT NULL,
`mailer_header` varchar(60) NOT NULL,
`mailer_type` enum('single','multi') NOT NULL,
`introduction` varchar(80) NOT NULL,
`status` enum('live','dead','draft') NOT NULL,
`flag` enum('sent','unsent') NOT NULL,
`date_mailer_created` int(11) NOT NULL,
`date_mailer_updated` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=29 ;
-- --------------------------------------------------------
--
-- Table structure for table `mailer_content`
--
CREATE TABLE `mailer_content` (
`id` int(11) NOT NULL auto_increment,
`headline` varchar(320) NOT NULL,
`content` text NOT NULL,
`mailer_id` int(11) NOT NULL,
`position` enum('left','right','centre') default NULL,
`tab_1_name` varchar(25) default NULL,
`tab_1_link` varchar(250) default NULL,
`tab_2_name` varchar(25) default NULL,
`tab_2_link` varchar(250) default NULL,
`tab_3_name` varchar(25) default NULL,
`tab_3_link` varchar(250) default NULL,
`tab_4_name` varchar(25) default NULL,
`tab_4_link` varchar(250) default NULL,
`created_at` int(10) NOT NULL,
`updated_at` int(10) NOT NULL,
PRIMARY KEY (`id`),
KEY `mailer_id` (`mailer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=16 ;
-- --------------------------------------------------------
--
-- Table structure for table `mailer_images`
--
CREATE TABLE `mailer_images` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(150) NOT NULL,
`filename` varchar(150) NOT NULL,
`mailer_id` int(11) NOT NULL,
`content_id` int(11) default NULL,
`date_created` int(10) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=49 ;
I am sure that is must be a problem with my sql I just do not know what the problem is
If you use SELECT DISTINCT SQL will not return dupplicated rows, if there are some.
SELECT DISTINCT * FROM `mailers` LEFT JOIN `mailer_content` ON `mailers`.`id` = `mailer_content`.`mailer_id` LEFT JOIN `mailer_images` ON `mailer_content`.`id` = `mailer_images`.`content_id` WHERE `mailers`.`id` = 26
U can use group by smthng. It will delete the same records.
but u can delete nonsame rows. Use smthng without same values in different rows in original table.
try this
SELECT * FROM mailers
LEFT JOIN mailer_content ON mailers.id = mailer_content.mailer_id
LEFT JOIN mailer_images ON mailer_content.id = mailer_images.content_id
WHERE mailers.id = 26 GROUP BY mailers.id
It doesn't look like an SQL isse to me; I suspect this is more likely down to the data in your tables.
My guess is that there are two rows in mailer_content where mailers.id = 26 and then two rows (or possibly 1 and 3) in mailer_images for each of the mailer_contents.
How many rows do each of the following queries return?
SELECT * FROM `mailers`
WHERE `mailers`.`id` = 26
SELECT * FROM `mailer_content`
WHERE `mailer_content`.`id` = 26
My guess is that the first returns 1 row (because it has a primary key on id) and that the second returns two rows.
That all may be fine but my guess is that the following query returns 4 records:
SELECT * FROM `mailer_content`
LEFT JOIN `mailer_images` ON `mailer_content`.`id` = `mailer_images`.`content_id`
WHERE `mailer_content`.`id` = 26
Because either each content has two images each OR one content has one image and the other has three.

MySQL slow query

SELECT
items.item_id, items.category_id, items.title, items.description, items.quality,
items.type, items.status, items.price, items.posted, items.modified,
zip_code.state_prefix, zip_code.city, books.isbn13, books.isbn10, books.authors,
books.publisher
FROM
(
(
items
LEFT JOIN bookitems ON items.item_id = bookitems.item_id
)
LEFT JOIN books ON books.isbn13 = bookitems.isbn13
)
LEFT JOIN zip_code ON zip_code.zip_code = items.item_zip
WHERE items.rid = $rid`
I am running this query to get the list of a user's items and their location. The zip_code table has over 40k records and this might be the issue. It currently takes up to 15 seconds to return a list of about 20 items! What can I do to make this query more efficient?
UPDATE: The following is the table creation code for the relevant tables. Sorry about the formatting!
CREATE TABLE `bookitems` (
`bookitem_id` int(10) unsigned NOT NULL auto_increment COMMENT 'BookItem ID',
`item_id` int(10) unsigned NOT NULL default '0' COMMENT 'Item ID',
`isbn13` varchar(13) NOT NULL default '' COMMENT 'Book ISBN13',
`modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT 'Date of Last Modification',
PRIMARY KEY (`bookitem_id`),
UNIQUE KEY `item_id` (`item_id`),
KEY `fk_bookitems_isbn13` (`isbn13`),
CONSTRAINT `fk_bookitems_isbn13` FOREIGN KEY (`isbn13`) REFERENCES `books` (`isbn13`),
CONSTRAINT `fk_bookitems_item_id` FOREIGN KEY (`item_id`) REFERENCES `items` (`item_id`)
) ENGINE=InnoDB AUTO_INCREMENT=82 DEFAULT CHARSET=latin1;
CREATE TABLE `books` (
`isbn13` varchar(13) NOT NULL default '' COMMENT 'Book ISBN13 (pk)',
`isbn10` varchar(10) NOT NULL default '' COMMENT 'Book ISBN10 (u)',
`title` text NOT NULL COMMENT 'Book Title',
`title_long` text NOT NULL,
`authors` text NOT NULL COMMENT 'Book Authors',
`publisher` text NOT NULL COMMENT 'ISBNdb publisher_text',
PRIMARY KEY (`isbn13`),
UNIQUE KEY `isbn10` (`isbn10`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `items` (
`item_id` int(10) unsigned NOT NULL auto_increment COMMENT 'Item ID',
`rid` int(10) unsigned NOT NULL default '0' COMMENT 'Item Owner User ID',
`category_id` int(10) unsigned NOT NULL default '0' COMMENT 'Item Category ID',
`title` tinytext NOT NULL COMMENT 'Item Title',
`description` text NOT NULL COMMENT 'Item Description',
`quality` enum('0','1','2','3','4','5') NOT NULL default '0' COMMENT 'Item Quality',
`type` enum('forsale','wanted','pending') NOT NULL default 'pending' COMMENT 'Item Status',
`price` int(6) unsigned NOT NULL default '0' COMMENT 'Price',
`posted` datetime NOT NULL default '0000-00-00 00:00:00' COMMENT 'Date of Listing',
`modified` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP COMMENT 'Date of Last Modification',
`status` enum('sold','found','flagged','removed','active','expired') NOT NULL default 'active',
`item_zip` int(5) unsigned zerofill NOT NULL default '00000',
PRIMARY KEY (`item_id`),
KEY `fk_items_rid` (`rid`),
KEY `fk_items_category_id` (`category_id`),
CONSTRAINT `fk_items_category_id` FOREIGN KEY (`category_id`) REFERENCES `categories` (`category_id`),
CONSTRAINT `fk_items_rid` FOREIGN KEY (`rid`) REFERENCES `users` (`rid`)
) ENGINE=InnoDB AUTO_INCREMENT=123 DEFAULT CHARSET=latin1;
CREATE TABLE `users` (
`rid` int(10) unsigned NOT NULL auto_increment COMMENT 'User ID',
`fid` int(10) unsigned NOT NULL default '0' COMMENT 'Facebook User ID',
`role_id` int(10) unsigned NOT NULL default '4',
`zip` int(5) unsigned zerofill NOT NULL default '00000' COMMENT 'Zip Code',
`joined` timestamp NOT NULL default CURRENT_TIMESTAMP COMMENT 'INSERT Timestamp',
`email` varchar(255) NOT NULL default '',
`notes` varchar(255) NOT NULL default '',
PRIMARY KEY (`rid`),
UNIQUE KEY `fid` (`fid`),
KEY `fk_users_role` (`role_id`),
CONSTRAINT `fk_users_role` FOREIGN KEY (`role_id`) REFERENCES `roles` (`role_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1013 DEFAULT CHARSET=latin1;
CREATE TABLE `zip_code` (
`id` int(11) unsigned NOT NULL auto_increment,
`zip_code` varchar(5) character set utf8 collate utf8_bin NOT NULL,
`city` varchar(50) character set utf8 collate utf8_bin default NULL,
`county` varchar(50) character set utf8 collate utf8_bin default NULL,
`state_name` varchar(50) character set utf8 collate utf8_bin default NULL,
`state_prefix` varchar(2) character set utf8 collate utf8_bin default NULL,
`area_code` varchar(3) character set utf8 collate utf8_bin default NULL,
`time_zone` varchar(50) character set utf8 collate utf8_bin default NULL,
`lat` float NOT NULL,
`lon` float NOT NULL,
`search_string` varchar(52) NOT NULL default '',
PRIMARY KEY (`id`),
KEY `zip_code` (`zip_code`)
) ENGINE=MyISAM AUTO_INCREMENT=42625 DEFAULT CHARSET=utf8;
SELECT items.item_id,
items.category_id,
items.title,
items.description,
items.quality,
items.TYPE,
items.status,
items.price,
items.posted,
items.modified,
zip_code.state_prefix,
zip_code.city,
books.isbn13,
books.isbn10,
books.authors,
books.publisher
FROM items
LEFT JOIN
bookitems
ON bookitems.item_id = items.item_id
LEFT JOIN
books
ON books.isbn13 = bookitems.isbn13
LEFT JOIN
zip_code
ON zip_code.zip_code = items.item_zip
WHERE items.rid = $rid
Create the following indexes:
items (rid)
bookitems (item_id)
books (isbn13)
zip_code (zip_code)
Your first option should be to optimise your database.
Is all those 40k rows useful data? Or can you move some old data to a table containing archived data? Are you using proper indexing? The list goes on..
The first question is what indexes you have. Do you have an index on zip_code (zip_code) ? How big are your other tables? Indexes that would obviously help are, as I say, zip_code (zip_code), then items (rid), bookitems (item_id), and books (isbn13).
I'd think you would almost certainly want on index on zip_code, that's likely used in almost any query against that table. You likely also want indexes on isbn13 and bookitems (item_id). I don't know what items (rid) is supposed to be. An index on that would help this query, but might or might not be generally useful.
Besides that, there are no obvious flaws in the query.
BTW, the parentheses around "items left join bookitems ..." are superfluous. Tables are joined left to right by default.
I am not sure about this just by looking at the query, but
It seems you are joining your rows with string data types, that is a bit slower to compare than using integers, like IDs, specially if not indexed.

MySQL multi-level parent selection/join question

I have a hopefully simple MySQL query question which is eluding me at late at night. I'm trying to do a SELECT which counts the number of instances of a set of data (orders) and groups those instances by a value which exists in a parent a couple levels above the order itself.
For example:
CREATE TABLE `so_test`.`categories` (
`id` int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=572395 DEFAULT CHARSET=latin1;
CREATE TABLE `so_test`.`product_group` (
`id` int(10) unsigned NOT NULL auto_increment,
`category_id` int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=572395 DEFAULT CHARSET=latin1;
CREATE TABLE `so_test`.`products` (
`id` int(10) unsigned NOT NULL auto_increment,
`product_group_id` int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=572395 DEFAULT CHARSET=latin1;
CREATE TABLE `so_test`.`orders` (
`id` int(10) unsigned NOT NULL auto_increment,
`product_id` int(10) unsigned NOT NULL auto_increment,
`customer_id` int(10) unsigned NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=572395 DEFAULT CHARSET=latin1;
What I'm looking to do is something in the neighborhood of:
SELECT count(orders.id), categoryId
FROM orders, categories WHERE
orders.customer_id in (1,2,3) GROUP BY orders.productId.productGroupId.categoryId
Assuming there are 17 orders for products in category 1, 2 orders for products in category 2, and 214 orders for category 3, what I'm hoping to get back is:
count(orders.id), categoryId
============================
17 1
2 2
214 3
If I was trying to group by say product_id I'd be fine..but the two-levels-up portion is throwing me.
Thanks!
Just join them together:
select categoryid, count(orders.id)
from category c
left join product_group pg on pg.category_id = c.id
left join products on p on p.product_group_id = pg.id
left join orders o on o.product_id = p.id
For categories without an order, count(orders.id) will return 0, while count(*) would return one or more, depending on the number of productgroups and products.
An inner join would not count categories without orders at all.

SQL: Subquery assistance

I'm trying to SELECT two values in one statement instead of two statements. The first statement counts how many entries won for a specific contest that has an id of 18. The second statement counts the total quantity of prizes for that contest.
Query 1:
SELECT
COUNT(*) FROM entries
WHERE entries.contest=18
AND entries.won=1
Query 2
SELECT SUM( quantity ) FROM prizes WHERE contest=18
I want to have both so I could compare them on the server-side and act upon that comparison.. So if we had say 3 entrants who won the 18th contest and the total quantity of prizes for the 18th contest is 5, do something...
Schema:
CREATE TABLE `entries` (
`id` int(2) unsigned NOT NULL auto_increment,
`message_id` bigint(8) unsigned default NULL,
`user` int(2) unsigned default NULL,
`username` varchar(50) NOT NULL,
`contest` int(2) unsigned default NULL,
`message` text,
`icon` text,
`twitter_url` text,
`follower` int(2) unsigned default NULL,
`entry_date` timestamp NOT NULL default '0000-00-00 00:00:00',
`won` int(1) default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
CREATE TABLE `prizes` (
`id` int(2) unsigned NOT NULL auto_increment,
`name` varchar(25) NOT NULL,
`contest` int(2) NOT NULL,
`quantity` int(2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
There is no users table because I control the entries, and I'm pretty sure I won't get any duplicates so that's why the user name, etc is stored for the entry row.
As the queries doesn't have anything in common at all, you would use two subqueries to get them in the same result:
select
(select count(*) from entries where contest = 18 and won = 1) as wins,
(select sum(quantity) from prizes where contest = 18) as quantity