MS SQL Basics: Joins

There are three categories joins fall into, inner, outer and cross. Outer joins consist of three types, left, right and full.

Lets have a quick look at the various joins. (On the right we've got two datasets we'll be using in the examples.)

Table a
aID title
1 a1
2 a2
3 a3
4 a4
Table b
bID title aID
1 b1 1
2 b2 2
3 b3 NULL
4 b4 NULL

Inner Join

Return rows that match in both tables. (Default join) SELECT * FROM a INNER JOIN b ON a.aid = b.aid
title aID
a1 1
a2 2
aID bID title
1 1 b1
2 2 b2



Left Outer Join

Return rows from the table on the left of the expression even if they dont match with the table on the right. SELECT * FROM a LEFT OUTER JOIN b ON a.aid = b.aid
title aID
a1 1
a2 2
a3 3
a4 4
aID bID title
1 1 b1
2 2 b2
NULL NULL NULL
NULL NULL NULL
 



Right Outer Join

Return rows from the table on the right of the expression even if they dont match with the table on the left. SELECT * FROM a RIGHT OUTER JOIN b ON a.aid = b.aid
title aID
a1 1
a2 2
NULL NULL
NULL NULL
aID bID title
1 1 b1
2 2 b2
3 3 b3
4 4 b4
 



Full Outer Join

Return rows from both the left and right tables even if they don't match in either. (left + right join) SELECT * FROM a FULL OUTER JOIN b ON a.aid = b.aid
title aID
a1 1
a2 2
a3 3
a4 4
NULL NULL
NULL NULL
aID bID title
1 1 b1
2 2 b2
NULL NULL NULL
NULL NULL NULL
3 3 b3
4 4 b4
 



Cross Join

Join each row from the left with each row from the right. Known as a "carthesian product" SELECT * FROM a CROSS JOIN b or SELECT * FROM a, b
title aID
a1 1
a2 2
a3 3
a4 4
a1 1
a2 2
a3 3
a4 4
a1 1
a2 2
a3 3
a4 4
a1 1
a2 2
a3 3
a4 4
aID bID title
1 1 b1
1 1 b1
1 1 b1
1 1 b1
2 2 b2
2 2 b2
2 2 b2
2 2 b2
3 3 b3
3 3 b3
3 3 b3
3 3 b3
4 4 b4
4 4 b4
4 4 b4
4 4 b4
 




Post/View comments
 

Custom/Composite controls with events

Creating custom controls that expose events can potentially prove to be quite tedious if we're presented with examples like the following:

Notice the following code, from the example you'll find on the MSDN links above:
 
public class MyButton: Control, IPostBackEventHandler {
 
  public event EventHandler Click;
 
  protected virtual void OnClick(EventArgs e) {
 
	 if (Click != null) {
		Click(this, e);
	 }   
  }
 
  public void RaisePostBackEvent(string eventArgument){
 
	 OnClick(new EventArgs());
  }
 
  protected override void Render(HtmlTextWriter output) {
	 output.Write("<INPUT TYPE = submit name = " + this.UniqueID + 
		" Value = 'Click Me' />");   
  }
}    
 

You will notice the implementation of the IPostBackEventHandler interface, which requires us to create the RaisePostBackEvent method.

But more interestingly, observe the render method where raw HTML are passed to the HtmlTextWriter instance.

Ideally something like the next snippet would make more sense, particularly in dealing with larger more complex controls - there is however a reason why the MSDN example was written in that manner.

 
HtmlInputSubmit _control = new HtmlInputSubmit()
{
	Name = this.UniqueID
};
_control.RenderControl(output);
 

One would find that all of a sudden the click event doesn't fire anymore, simply because the control would now contain a child control that needs to propagate its events to the parent control - since the MSDN example isn't using any child controls, the example should work just fine. (Personally I feel its a bit of a pointless example.)

ASP.net provides a technique called event bubbling to aid us in the propagation of these events. Observe the following snippet:

 
public class SearchBox : CompositeControl
{
    public event EventHandler Click;
    TextBox _TextBox = new TextBox();
    Button _Button = new Button()
    {
        CommandName = "Click",
        Text = "Search"
    };
 
    [Browsable(true)]
    [Category("Appearance")]
    public string Text
    {
        get
        {
            return _TextBox.Text;
        }
        set
        {
            _TextBox.Text = value;
        }
    }
 
    protected virtual void OnClick(EventArgs e)
    {
        if (Click != null)
        {
            Click(this, e);
        }
    }
 
    protected override bool OnBubbleEvent(object source, EventArgs args)
    {
        CommandEventArgs _CommandEventArgs = args as CommandEventArgs;
        if (_CommandEventArgs != null)
        {
            if (_CommandEventArgs.CommandName == "Click")
            {
                OnClick(args);
                return true;
            }
        }
        return false;
    }
 
    protected override void CreateChildControls()
    {
        this.Controls.Add(_TextBox);
        this.Controls.Add(_Button);
        base.CreateChildControls();
    }
}
 

In the preceding snippet:
  • Inherit from the CompositeControl class; which is like a base class for controls that have child controls.
  • Added two child controls, textbox and button, and assign a CommandName to the button, which will be used in our "bubble".
  • Override the OnBubbleEvent, where we check if the appropriate CommandName was raised - in this case "Click", which raises any event handlers attached to the button.

To read more about "Bubbling an Event" click here.

Post/View comments
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27