<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: SQL Help for Photo Battle Blog</title>
	<atom:link href="http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog/feed" rel="self" type="application/rss+xml" />
	<link>http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog</link>
	<description>The Weblog of Erik J. Barzeski</description>
	<pubDate>Sun, 06 Jul 2008 08:06:17 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
		<item>
		<title>By: lottadot</title>
		<link>http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog#comment-46200</link>
		<dc:creator>lottadot</dc:creator>
		<pubDate>Mon, 25 Feb 2008 23:51:08 +0000</pubDate>
		<guid isPermaLink="false">http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog#comment-46200</guid>
		<description>That's quite a bit to select constantly. Joins are expensive.  I'd create a third table that'd hold the post_id and who won. Then create a trigger - on close of a battle it updates. (or if you don't want to mess with a trigger a cron'd script or something that kicks off a script that'll handle it.</description>
		<content:encoded><![CDATA[<p>That's quite a bit to select constantly. Joins are expensive.  I'd create a third table that'd hold the post_id and who won. Then create a trigger - on close of a battle it updates. (or if you don't want to mess with a trigger a cron'd script or something that kicks off a script that'll handle it.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Charles Schmidt</title>
		<link>http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog#comment-46195</link>
		<dc:creator>Charles Schmidt</dc:creator>
		<pubDate>Mon, 25 Feb 2008 21:04:25 +0000</pubDate>
		<guid isPermaLink="false">http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog#comment-46195</guid>
		<description>I have never used MySQL, only T-SQL (microsoft sql server), so my queries might not work on your system out of the box.  Stupid nonstandard language  :evil: 

Might I suggest setting your table up so that the choice/vote column is only ever 1 or 0.  ("1" = vote for photo 1, "0" = vote for photo 2).   This should allow you to build slightly faster queries by not having to search on the vote column (also lets you use BIT, but then you might have to convert() later,  I'm not sure how MySQL handles bit-&#62;int conversions.  At least in the tests I did locally, MS SQL won't do the conversion implictly, but I didn't see any performance drops adding an explicit conversion).

The first stat you already have:

&lt;pre&gt;
select 
	post_id,
	sum(choice) as ones,
	count(ip) - sum(choice) as twos
from 
	votes
group by
	post_id
&lt;/pre&gt;

The second stat ("wins") you're looking for:

&lt;pre&gt;
select 
	post_id,
	sum(choice) as one_vote,
	count(ip) - sum(choice) as two_vote,
	case 
		when sum(choice) &#62; count(ip) - sum(choice) then 1
		when sum(choice) &#60; count(ip) - sum(choice) then 2 
		else -1 
	end
from 
	votes
group by
	post_id
&lt;/pre&gt;

or in aggregate form:

&lt;pre&gt;
select 
	sum(ones) as one_wins,
	sum(twos) as two_wins,
	sum(ties) as ties
from
(
	select 
		post_id,
		case when sum(choice) &#62; count(ip) - sum(choice) then 1 else 0 end as ones,
		case when sum(choice) &#60; count(ip) - sum(choice) then 1 else 0 end as twos,
		case when sum(choice) = count(ip) - sum(choice) then 1 else 0 end as ties
			
	from 
		votes
	group by
		post_id
) a
&lt;/pre&gt;


Alternatively/at the very least,  you should modify Patrick's logic to include cases where 1 photo receives all of the votes:

&lt;pre&gt;
select
	coalesce(ones.post_id,twos.post_id) as post_id,
	isnull(ones.votes,0) as one_vote,
	isnull(twos.votes,0) as two_vote,
	case 
		when isnull(ones.votes,0) &#62; isnull(twos.votes,0) then 1 
		when isnull(ones.votes,0) &#60; isnull(twos.votes,0) then 2
		else -1
	end
from 
	(select post_id, count(*) as votes from votes where choice = 1 group by post_id) as ones 
full outer join
	(select post_id, count(*) as votes from votes where choice = 2 group by post_id) as twos 
on
	ones.post_id = twos.post_id
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>I have never used MySQL, only T-SQL (microsoft sql server), so my queries might not work on your system out of the box.  Stupid nonstandard language  <img src='http://nslog.com/wp-includes/images/smilies/icon_evil.gif' alt=':evil:' class='wp-smiley' /> </p>
<p>Might I suggest setting your table up so that the choice/vote column is only ever 1 or 0.  ("1" = vote for photo 1, "0" = vote for photo 2).   This should allow you to build slightly faster queries by not having to search on the vote column (also lets you use BIT, but then you might have to convert() later,  I'm not sure how MySQL handles bit-&gt;int conversions.  At least in the tests I did locally, MS SQL won't do the conversion implictly, but I didn't see any performance drops adding an explicit conversion).</p>
<p>The first stat you already have:</p>
<pre>
select
	post_id,
	sum(choice) as ones,
	count(ip) - sum(choice) as twos
from
	votes
group by
	post_id
</pre>
<p>The second stat ("wins") you're looking for:</p>
<pre>
select
	post_id,
	sum(choice) as one_vote,
	count(ip) - sum(choice) as two_vote,
	case
		when sum(choice) &gt; count(ip) - sum(choice) then 1
		when sum(choice) &lt; count(ip) - sum(choice) then 2
		else -1
	end
from
	votes
group by
	post_id
</pre>
<p>or in aggregate form:</p>
<pre>
select
	sum(ones) as one_wins,
	sum(twos) as two_wins,
	sum(ties) as ties
from
(
	select
		post_id,
		case when sum(choice) &gt; count(ip) - sum(choice) then 1 else 0 end as ones,
		case when sum(choice) &lt; count(ip) - sum(choice) then 1 else 0 end as twos,
		case when sum(choice) = count(ip) - sum(choice) then 1 else 0 end as ties

	from
		votes
	group by
		post_id
) a
</pre>
<p>Alternatively/at the very least,  you should modify Patrick's logic to include cases where 1 photo receives all of the votes:</p>
<pre>
select
	coalesce(ones.post_id,twos.post_id) as post_id,
	isnull(ones.votes,0) as one_vote,
	isnull(twos.votes,0) as two_vote,
	case
		when isnull(ones.votes,0) &gt; isnull(twos.votes,0) then 1
		when isnull(ones.votes,0) &lt; isnull(twos.votes,0) then 2
		else -1
	end
from
	(select post_id, count(*) as votes from votes where choice = 1 group by post_id) as ones
full outer join
	(select post_id, count(*) as votes from votes where choice = 2 group by post_id) as twos
on
	ones.post_id = twos.post_id
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: Kevin Hillabolt</title>
		<link>http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog#comment-46146</link>
		<dc:creator>Kevin Hillabolt</dc:creator>
		<pubDate>Fri, 22 Feb 2008 17:12:22 +0000</pubDate>
		<guid isPermaLink="false">http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog#comment-46146</guid>
		<description>I'm guessing you either have:

1. limit the ability to vote one time per IP/Post, or 2. have a unique index on the votes table (ip_address, post_id)?

Either way, Patrick's solution appears to do the trick on MySQL.

&lt;blockquote&gt;&lt;p&gt;case when ones.vote = twos.vote then 1 else 0 end as tie&lt;/p&gt;&lt;/blockquote&gt;

1 representing true.</description>
		<content:encoded><![CDATA[<p>I'm guessing you either have:</p>
<p>1. limit the ability to vote one time per IP/Post, or 2. have a unique index on the votes table (ip_address, post_id)?</p>
<p>Either way, Patrick's solution appears to do the trick on MySQL.</p>
<p class="quote_header"><a href="http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog#comment-">Kevin Hillabolt said</a> on February 22, 2008:</p>
<blockquote cite="http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog#comment-"><p>case when ones.vote = twos.vote then 1 else 0 end as tie</p>
</blockquote>
<p>1 representing true.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Patrick Burleson</title>
		<link>http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog#comment-46145</link>
		<dc:creator>Patrick Burleson</dc:creator>
		<pubDate>Fri, 22 Feb 2008 16:39:58 +0000</pubDate>
		<guid isPermaLink="false">http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog#comment-46145</guid>
		<description>Oh, forgot the edge case of a tie. That's just another addition to the case statement returning a value to represent a tie, maybe 0.</description>
		<content:encoded><![CDATA[<p>Oh, forgot the edge case of a tie. That's just another addition to the case statement returning a value to represent a tie, maybe 0.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Patrick Burleson</title>
		<link>http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog#comment-46144</link>
		<dc:creator>Patrick Burleson</dc:creator>
		<pubDate>Fri, 22 Feb 2008 16:36:58 +0000</pubDate>
		<guid isPermaLink="false">http://nslog.com/2008/02/21/sql_help_for_photo_battle_blog#comment-46144</guid>
		<description>I think something like the following will do what you want:

select
post_id,
ones.votes as one_vote,
twos.votes as two_vote,
case when ones.votes &#62; twos.votes then 1 else 2 end as winner

from 

(select post_id, count(*) as votes from votes where choice = 1 group by post_id) as ones join
(select post_id, count(*) as votes from votes where choice = 2 group by post_id) as twos on 
ones.post_id = twos.post_id

Although, that syntax might not work with MySQL. It works for Postgresql and SQL Server.</description>
		<content:encoded><![CDATA[<p>I think something like the following will do what you want:</p>
<p>select<br />
post_id,<br />
ones.votes as one_vote,<br />
twos.votes as two_vote,<br />
case when ones.votes &gt; twos.votes then 1 else 2 end as winner</p>
<p>from </p>
<p>(select post_id, count(*) as votes from votes where choice = 1 group by post_id) as ones join<br />
(select post_id, count(*) as votes from votes where choice = 2 group by post_id) as twos on<br />
ones.post_id = twos.post_id</p>
<p>Although, that syntax might not work with MySQL. It works for Postgresql and SQL Server.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
