Fetching data from multiple tables in one MySQL query – Part 2

A few days back, I mentioned in a post how to fetch data from multiple tables in one MySQL query using multiple and nested SELECT statements. Today I’m going to present a more elegant way to do that using INNER JOIN.

Let’s reiterate the problem first –

We have 2 tables – tableA and tableB. The structure of these 2 tables are like -

tableA

`id` int(11) NOT NULL AUTO_INCREMENT,
`home_id` int(11) DEFAULT NULL,
`away_id` int(11) DEFAULT NULL,
`datetime` datetime DEFAULT NULL,
`status` int(4) DEFAULT NULL,
PRIMARY KEY (`id`)

tableB

`id` int(11) NOT NULL AUTO_INCREMENT,
`team_name` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
PRIMARY KEY (`id`)

Here home_id and away_id in tableA are foreign keys that references to id in tableB. We want to pick data from tableA according to some condition – for example, status is less than 4. But we want team names instead of ids. That means we need to pick team names from tableB.

Now if we needed just home team or away team, that would have been easy as we can use an INNER JOIN straightway -

SELECT tableA.id,
tableB.team_name AS home_team,
tableA.datetime
FROM tableA
INNER JOIN tableB
ON tableA.home_id = tableB.id
WHERE tableA.status < 4;

But we need both home and away team and they refer to 2 different rows on tableB. So, it is not possible to pick both the names using one INNER JOIN. Difficult situation, huh? Aliases come to the rescue! We can use an alias for tableB and inner join that to the first 2 tables. Here’s the full query –

SELECT tableA.id,
tableB.team_name AS home_team,
tableB_Alias.team_name AS away_team,
tableA.datetime
FROM tableA
INNER JOIN tableB
ON tableA.home_id = tableB.id
INNER JOIN tableB AS tableB_Alias
ON tableA.away_id = tableB_Alias.id
WHERE tableA.status < 4;

Fetching data from multiple tables in one MySQL query

Often we need to use SELECT queries that will fetch data from multiple tables. One option is to use INNER JOIN, LEFT JOIN etc. But in this case described below I couldn’t find a way to use those. Lets say we have 2 tables – tableA and tableB. The structure of these 2 tables are like -

tableA

`id` int(11) NOT NULL AUTO_INCREMENT,
`home_id` int(11) DEFAULT NULL,
`away_id` int(11) DEFAULT NULL,
`datetime` datetime DEFAULT NULL,
`status` int(4) DEFAULT NULL,
PRIMARY KEY (`id`)

tableB

`id` int(11) NOT NULL AUTO_INCREMENT,
`team_name` varchar(50) CHARACTER SET utf8 DEFAULT NULL,
PRIMARY KEY (`id`)

Here home_id and away_id in tableA are foreign keys that references to id in tableB. We want to pick data from tableA according to some condition – for example, status is less than 4. But we want team names instead of ids. That means we need to pick team names from tableB.

Here’s a simple way to do it –

SELECT tableA.id,
(SELECT tableB.team_name FROM tableB WHERE tableA.home_id = tableB.id) AS home_team,
(SELECT tableB.team_name FROM tableB WHERE tableA.away_id = tableB.id) AS away_team,
tableA.datetime
FROM tableA
WHERE tableA.status < 4;

It is important to use aliases here. You have to specify ‘AS home_team’ or ‘AS away_team’ etc in the inner SELECT commands.

There may be more efficient and elegant methods than this – using multiple selects in one query. Can anybody suggest some?

Make them all glow, can you ?

Here is Luminr, a simple puzzle game with an interesting user interface. A result of my recent experimentation with UI. You can also play the game on your iPhone, download it form the appstore.

You are to click on orbs arranged in a grid to make them all glow. Clicking on an orb changes its state from unlit to lit or lit to unlit along with the neighboring orbs. Turn on all the orbs to pass a level with as few moves as you can.

There are 9 levels, each with more orbs than the previous one. Two difficulty modes. In the easy mode, all orbs are unlit in the beginning and in the hard mode, some orbs are already lit to make things difficult for the player.

Let’s Go A Hunting

I wanted to draw a bunch of stick figure men carrying spears, going on a grand hunting event. There will be at least 15 men in the group. Of course I could draw them all by hand, but I decided to put my Photoshop Scripting abilities to good use.

people

I started with a drawing of three stick figure hunters. This drawing was made in Adoble Flash CS3 using a Wacom Bamboo tablet. Separating the legs from upper body gives me a set of 3 upper bodies and 3 pairs of legs. We can make 3X3=9 different hunters using these. The idea is very simple, match upper body with legs to form a member of the hunting group. I decided to randomly pick an upper body and a pair of legs to form each member of the group and keep looping until there isn’t space left on the image.

This is the script I wrote:

var defaultRulerUnits = preferences.rulerUnits
preferences.rulerUnits = Units.PIXELS

var imageWidth = 965 ;
var imageHeight = 150 ;

var legWidth = 60 ;
var legHeight = 75 ;

var torsoWidth = 75 ;
var torsoHeight = 150 ;

var nLeg = 3 ;
var nTorso = 3 ;

//open leg images
for(i=1;i<=nLeg;i++) {
	var fileRef = new File("C://hunt//leg"+i+".png");

	var docRef = app.open(fileRef);
	fileRef=null;

	docRef=null;
}

//open upper body images
for(i=1;i<=nTorso;i++) {

	var fileRef = new File("C://hunt//torso"+i+".png");
	var docRef = app.open(fileRef);

	fileRef=null;
	docRef=null;
}

var newDocument = documents.add(imageWidth,imageHeight);

//make some random hunters
for(j=0;j<17;j++) {

		app.activeDocument = app.documents[Math.floor(Math.random()*nLeg)];

		var AD = app.activeDocument;
		AD.artLayers[0].copy();
		app.activeDocument = newDocument;

		var layer = newDocument.paste();
		layer.translate(j*legWidth-imageWidth/2,legHeight);

		app.activeDocument = app.documents[3+Math.floor(Math.random()*nTorso)];

		AD = app.activeDocument;
		AD.artLayers[0].copy();
		app.activeDocument = newDocument;

		var layer = newDocument.paste();
		layer.translate(j*legWidth-imageWidth/2,legHeight/2+2);		

		layer.merge()

}

//close all files except for the final result
for(i=app.documents.length-2;i>=0;i--) {

	var AD = app.documents[i]
	AD.close(SaveOptions.DONOTSAVECHANGES);
}

preferences.rulerUnits = defaultRulerUnits; 

And here is the result.

hunt

Since the hard part was already done, I decide to play around a little more and came up with this for a banner here. Hopefully It will stay there for a day :)

shikar1

Java Applet and Javascript message passing

I did this quite a while a ago, thought I should share this.

To call a js function foo from java applet :

String [] stringArgs = new String[2];

stringArgs[0] = "first arg from Java";
stringArgs[1] = "second arg from Java";

mainWindow.call("foo", stringArgs);

To call a function foo() in a java applet named bar, do the following in javascript:

document.bar.foo(param1, param2, ....) ;

Connext : the next generation of ‘Connect the Dots’

screen-shot-1screen-shot-2screen-shot-3

Connext is a puzzle game based on the simple concept of ‘Connecting the Dots’. Connect dots to form whatever shape you can. Make loops to gain score, bigger loops are better. Gain bonus points for making interesting shapes. Trap bonus items inside your loops to claim advantage.

You can play the game here at mochimedia’s site. Thanks to mochi leaderboards, You can also invite and challenge your Facebook friends to play the game.

Hope you’ll like it as much as Jeff at 8bitrocket, who likes this game “A LOT” and calls it a gem. And if you really do, please do let us know by dropping a line here or at the newgrounds page. Suggestions on how we can improve this, a bug report or any sort of feedback is welcomed.

That’s all for now. Time to go connexting :D

The Right-Click Menu in Flash

The right click menu is actually called the context menu. I did not know that. I had to go through several forums and blogs on the net before stumbling upon this piece of information.

Usually one does not need to bother about this menu. But if you are working on a game, you might want to disable this menu. Because the ‘play’ option in the context menu gives your user the ability to play the movie when you would rather have it to stopped. I leave it up to your imagination figuring out how one can cheat or mess things up from here.

To disable the context menu, put this line of code on the first frame, or in any other frame from where you want the context menu to be disabled.

stage.showMenu =  false ;

This will not actually disable the context menu, but hide most parts of it.

Disabling the context menu would help those would be cheaters from cheating their way through your game. But that’s not all we can do with this menu. We can also add some customized menu options as well. To do so, one has to follow these simple steps.

  • Make a new context menu
  • Create customized menu item
  • Attach event listener with the custom menu item
  • Insert the custom item into the new menu
  • Set the new menu as the current context menu

For example, in our games we usually put a customized menu item linking back to our homepage. To do this, we use the following piece of code.

function initMenu() {
	var m:String='© muktosoft';

	var cm:ContextMenu=new ContextMenu();
	var item:ContextMenuItem=new ContextMenuItem(m);

	item.addEventListener(ContextMenuEvent.MENU_ITEM_SELECT,gotoMukto_);
	cm.hideBuiltInItems();
	cm.customItems.push(item);
	this.contextMenu = cm ;

}

function gotoMukto_(evt:ContextMenuEvent):void {
	navigateToURL(new URLRequest("http://www.muktosoft.com"), "_blank");
}

Stroke hinting

Anyone who have tried making rectangles with rounded corner must have noticed how odd those corners look as they tend to get pixelated and stick out from the body of the rectangle. See the image bellow if you still don’t get what I mean. Notice how odd those pixalted corners look. The same thing can happen with a curved line as well.

stroke_hinting_pixelated

This is due to the anti-aliasing performed on the curved lines by flash. This looks worst when the rounded part is small. The problem is still present when the curved part is large, but it becomes less noticeable. Anti-aliasing is generally a very helpful feature. This case is one of the rare exceptions when anti-aliasing is better not performed.

To let flash know that you don’t want anti-aliasing to be performed on your curved lines, you have to enable stroke hinting. When stroke hinting is used, flash colors the whole pixels only during rendering. Skips the fractional pixels. Thus anti-aliasing is avoided. See result after enabling stroke-hinting in the image bellow.

stroke_hinting_hinted

Python: C++ style cin, cout in Python

Ready to bring some flavor of C++ into python? If you like cout, cin in C++ and also a python programmer, you’d definitely like this snippet.

import sys
class ostream:
    def __init__(self, file):
        self.file = file

    def __lshift__(self, obj):
        self.file.write(str(obj));
        return self
cout = ostream(sys.stdout)
cerr = ostream(sys.stderr)
endl = '\n'

x, y = 'Printing', 'like C++'
cout << x << " " << y << endl

I found this and a lot of other cool stuffs from Peter Norvig’s blog. I highly recommended subscribing to this blog.

Python: Working in Unicode

While working on unicode based characters in python, you’ll often come across this type error message (this cost me a while to fix).


UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)

This will happen if you do not set your character encoding in your python file to UTF-8. First you need to make sure the first few lines of your programm looks like this.


#!/usr/bin/python
# coding=utf-8
# -*- encoding: utf-8 -*-

This enables you to write unicode characters in your source code. But this does not enable you to print them in console and you’ll still keep getting the same error I previously mentioned.

To solve this you need to add the following code in your /usr/lib/python2.5/sitecustomize.py file (This might change depending your installed python version)


import sys;
sys.setdefaultencoding('utf-8')

The interesting part is, if you try to do that in your source file, it won’t work, I kept getting this error

AttributeError: 'module' object has no attribute 'setdefaultencoding'

I’m not sure why python does this, but a reasonable explanation would be not to change the character encoding in runtime, that could pose vulnerability to the system.

utf-8 isn’t default in python, maybe they’ll fix this in python 3.0