Index: tests/phpunit/tests/meta.php
===================================================================
--- tests/phpunit/tests/meta.php	(revision 25254)
+++ tests/phpunit/tests/meta.php	(working copy)
@@ -150,4 +150,25 @@
 		$this->assertInternalType( 'int', update_metadata( 'user', $this->author->ID, $key, $value2 ) );
 		$this->assertEquals( $expected2, get_metadata( 'user', $this->author->ID, $key, true ) );
 	}
+
+	function test_meta_type_cast() {
+		$post_id1 = $this->factory->post->create();
+		add_post_meta( $post_id1, 'num_as_longtext', 123 );
+		$post_id2 = $this->factory->post->create();
+		add_post_meta( $post_id2, 'num_as_longtext', 99 );
+
+		$posts = new WP_Query( array(
+			'fields' => 'ids',
+			'post_type' => 'any',
+			'meta_key' => 'num_as_longtext',
+			'meta_value' => '0',
+			'meta_compare' => '>',
+			'meta_type' => 'UNSIGNED',
+			'orderby' => 'meta_value',
+			'order' => 'ASC'
+		) );
+
+		$this->assertEquals( array( $post_id2, $post_id1 ), $posts->posts );
+		$this->assertEquals( 2, substr_count( $posts->request, 'CAST(' ) );
+	}
 }
Index: src/wp-includes/query.php
===================================================================
--- src/wp-includes/query.php	(revision 25250)
+++ src/wp-includes/query.php	(working copy)
@@ -2420,7 +2420,12 @@
 						break;
 					case $q['meta_key']:
 					case 'meta_value':
-						$orderby = "$wpdb->postmeta.meta_value";
+						if ( isset( $q['meta_type'] ) ) {
+							$meta_type = get_meta_type( $q['meta_type'] );
+							$orderby = "CAST($wpdb->postmeta.meta_value AS {$meta_type})";
+						} else {
+							$orderby = "$wpdb->postmeta.meta_value";
+						}	
 						break;
 					case 'meta_value_num':
 						$orderby = "$wpdb->postmeta.meta_value+0";
Index: src/wp-includes/meta.php
===================================================================
--- src/wp-includes/meta.php	(revision 25250)
+++ src/wp-includes/meta.php	(working copy)
@@ -604,6 +604,30 @@
 }
 
 /**
+ * Given a meta type, return the appropriate alias if applicable
+ *
+ * @since 3.7.0
+ *
+ * @see WP_Meta_Query
+ *
+ * @param string $type MySQL type to cast meta_value
+ * @return string MySQL type
+ */
+function get_meta_type( $type = '' ) {
+	if ( empty( $type ) )
+		return 'CHAR';
+
+	$meta_type = strtoupper( $type );
+
+	if ( ! in_array( $meta_type, array( 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED', 'NUMERIC' ) ) )
+		return 'CHAR';
+
+	if ( 'NUMERIC' == $meta_type )
+		$meta_type = 'SIGNED';
+
+	return $meta_type;
+}
+/**
  * Container class for a multiple metadata query
  *
  * @since 3.2.0
@@ -744,13 +768,8 @@
 
 		foreach ( $queries as $k => $q ) {
 			$meta_key = isset( $q['key'] ) ? trim( $q['key'] ) : '';
-			$meta_type = isset( $q['type'] ) ? strtoupper( $q['type'] ) : 'CHAR';
+			$meta_type = get_meta_type( isset( $q['type'] ) ? $q['type'] : '' );
 
-			if ( 'NUMERIC' == $meta_type )
-				$meta_type = 'SIGNED';
-			elseif ( ! in_array( $meta_type, array( 'BINARY', 'CHAR', 'DATE', 'DATETIME', 'DECIMAL', 'SIGNED', 'TIME', 'UNSIGNED' ) ) )
-				$meta_type = 'CHAR';
-
 			$meta_value = isset( $q['value'] ) ? $q['value'] : null;
 
 			if ( isset( $q['compare'] ) )
