diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index 7bc886022cc1c206d98aa10bbcd2ce186cb866fd..e5c177503fa441e556c1a6fac444f2c8d81e4640 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -796,3 +796,28 @@ aaa
 show warnings;
 Level	Code	Message
 drop table t1, t2;
+CREATE TABLE t1 (a tinyint(3), b varchar(255), PRIMARY KEY  (a));
+INSERT INTO t1 VALUES (1,'-----'), (6,'Allemagne'), (17,'Autriche'), 
+(25,'Belgique'), (54,'Danemark'), (62,'Espagne'), (68,'France');
+CREATE TABLE t2 (a tinyint(3), b tinyint(3), PRIMARY KEY  (a), KEY b (b));
+INSERT INTO t2 VALUES (1,1), (2,1), (6,6), (18,17), (15,25), (16,25),
+(17,25), (10,54), (5,62),(3,68);
+CREATE VIEW v1 AS select t1.a, concat(t1.b,'') AS b, t1.b as real_b from t1;
+explain 
+SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1
+where t2.b=v1.a GROUP BY t2.b;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t2	index	b	b	2	NULL	10	Using index
+1	PRIMARY	t1	eq_ref	PRIMARY	PRIMARY	1	test.t2.b	1	
+SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1
+where t2.b=v1.a GROUP BY t2.b;
+a	b	real_b
+1	-----	-----
+6	Allemagne	Allemagne
+17	Autriche	Autriche
+25	Belgique	Belgique
+54	Danemark	Danemark
+62	Espagne	Espagne
+68	France	France
+DROP VIEW v1;
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index fb9835c5d7f5c75fd06bd5dd4b82e1fb409e31dc..ce1e4e59600fe65edde84a57acef334a209e9e58 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -632,3 +632,26 @@ group by t1.c1;
 show warnings;
 drop table t1, t2;
 
+#
+# Bug #20466: a view is mixing data when there's a trigger on the table
+#
+CREATE TABLE t1 (a tinyint(3), b varchar(255), PRIMARY KEY  (a));
+
+INSERT INTO t1 VALUES (1,'-----'), (6,'Allemagne'), (17,'Autriche'), 
+    (25,'Belgique'), (54,'Danemark'), (62,'Espagne'), (68,'France');
+
+CREATE TABLE t2 (a tinyint(3), b tinyint(3), PRIMARY KEY  (a), KEY b (b));
+
+INSERT INTO t2 VALUES (1,1), (2,1), (6,6), (18,17), (15,25), (16,25),
+ (17,25), (10,54), (5,62),(3,68);
+
+CREATE VIEW v1 AS select t1.a, concat(t1.b,'') AS b, t1.b as real_b from t1;
+
+explain 
+SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1
+where t2.b=v1.a GROUP BY t2.b;
+SELECT straight_join sql_no_cache v1.a, v1.b, v1.real_b from t2, v1
+where t2.b=v1.a GROUP BY t2.b;
+
+DROP VIEW v1;
+DROP TABLE t1,t2;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index a7158960ed05557def4160716fafb16b9d145a12..39f5b43b05e63d3859f3d3160fd771c2963f950c 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -13066,10 +13066,11 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
   param->copy_funcs.empty();
   for (i= 0; (pos= li++); i++)
   {
-    if (pos->real_item()->type() == Item::FIELD_ITEM)
+    Item *real_pos= pos->real_item();
+    if (real_pos->type() == Item::FIELD_ITEM)
     {
       Item_field *item;
-      pos= pos->real_item();
+      pos= real_pos;
       if (!(item= new Item_field(thd, ((Item_field*) pos))))
 	goto err;
       pos= item;
@@ -13108,12 +13109,13 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
       }				
       }
     }
-    else if ((pos->type() == Item::FUNC_ITEM ||
-	      pos->type() == Item::SUBSELECT_ITEM ||
-	      pos->type() == Item::CACHE_ITEM ||
-	      pos->type() == Item::COND_ITEM) &&
-	     !pos->with_sum_func)
+    else if ((real_pos->type() == Item::FUNC_ITEM ||
+	      real_pos->type() == Item::SUBSELECT_ITEM ||
+	      real_pos->type() == Item::CACHE_ITEM ||
+	      real_pos->type() == Item::COND_ITEM) &&
+	     !real_pos->with_sum_func)
     {						// Save for send fields
+      pos= real_pos;
       /* TODO:
 	 In most cases this result will be sent to the user.
 	 This should be changed to use copy_int or copy_real depending