diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index e29c2ae206..ae078d86de 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -13,6 +13,8 @@
  */
 #include "postgres.h"
 
+#include <math.h>
+
 #include "access/xact.h"
 #include "catalog/pg_type.h"
 #include "commands/createas.h"
@@ -54,6 +56,9 @@ explain_get_index_name_hook_type explain_get_index_name_hook = NULL;
 #define X_CLOSE_IMMEDIATE 2
 #define X_NOWHITESPACE 4
 
+/* Check if float/double has any decimal number */
+#define HAS_DECIMAL(x) (floor(x) != x)
+
 static void ExplainOneQuery(Query *query, int cursorOptions,
 							IntoClause *into, ExplainState *es,
 							const char *queryString, ParamListInfo params,
@@ -1643,16 +1648,29 @@ ExplainNode(PlanState *planstate, List *ancestors,
 		double		total_ms = 1000.0 * planstate->instrument->total / nloops;
 		double		rows = planstate->instrument->ntuples / nloops;
 
+		/*
+		 * If the number of loops is greater than one, display the
+		 * actual rows up to two decimal places instead of rounding
+		 * off the value.
+		 */
 		if (es->format == EXPLAIN_FORMAT_TEXT)
 		{
 			if (es->timing)
+			{
+				appendStringInfo(es->str, " (actual time=%.3f..%.3f",
+								 startup_ms, total_ms);
 				appendStringInfo(es->str,
-								 " (actual time=%.3f..%.3f rows=%.0f loops=%.0f)",
-								 startup_ms, total_ms, rows, nloops);
+								 (nloops == 1 || !HAS_DECIMAL(rows)) ?
+								 " rows=%.0f loops=%.0f)" : " rows=%.2f loops=%.0f)",
+								 rows, nloops);
+			}
 			else
+			{
 				appendStringInfo(es->str,
-								 " (actual rows=%.0f loops=%.0f)",
+								 (nloops == 1 || !HAS_DECIMAL(rows)) ?
+								 " (actual rows=%.0f loops=%.0f)" : " (actual rows=%.2f loops=%.0f)",
 								 rows, nloops);
+			}
 		}
 		else
 		{
@@ -1663,7 +1681,7 @@ ExplainNode(PlanState *planstate, List *ancestors,
 				ExplainPropertyFloat("Actual Total Time", "ms", total_ms,
 									 3, es);
 			}
-			ExplainPropertyFloat("Actual Rows", NULL, rows, 0, es);
+			ExplainPropertyFloat("Actual Rows", NULL, rows, (nloops == 1 || !HAS_DECIMAL(rows)) ? 0 : 2, es);
 			ExplainPropertyFloat("Actual Loops", NULL, nloops, 0, es);
 		}
 	}
@@ -1707,18 +1725,30 @@ ExplainNode(PlanState *planstate, List *ancestors,
 			rows = instrument->ntuples / nloops;
 
 			ExplainOpenWorker(n, es);
+			/*
+			 * If the number of loops is greater than one, display the
+			 * actual rows up to two decimal places instead of rounding
+			 * off the value.
+			 */
 
 			if (es->format == EXPLAIN_FORMAT_TEXT)
 			{
 				ExplainIndentText(es);
 				if (es->timing)
+				{
+					appendStringInfo(es->str, "actual time=%.3f..%.3f",
+									 startup_ms, total_ms);
 					appendStringInfo(es->str,
-									 "actual time=%.3f..%.3f rows=%.0f loops=%.0f\n",
-									 startup_ms, total_ms, rows, nloops);
+									 (nloops == 1 || !HAS_DECIMAL(rows)) ?
+									 " rows=%.0f loops=%.0f" : " rows=%.2f loops=%.0f",
+									 rows, nloops);
+				}
 				else
-					appendStringInfo(es->str,
-									 "actual rows=%.0f loops=%.0f\n",
+				{
+					appendStringInfo(es->str, (nloops == 1 || !HAS_DECIMAL(rows)) ?
+									 "actual rows=%.0f loops=%.0f" : "actual rows=%.2f loops=%.0f",
 									 rows, nloops);
+				}
 			}
 			else
 			{
@@ -1729,7 +1759,8 @@ ExplainNode(PlanState *planstate, List *ancestors,
 					ExplainPropertyFloat("Actual Total Time", "ms",
 										 total_ms, 3, es);
 				}
-				ExplainPropertyFloat("Actual Rows", NULL, rows, 0, es);
+				ExplainPropertyFloat("Actual Rows", NULL, rows, 
+						(nloops == 1 || !HAS_DECIMAL(rows)) ? 0 : 2, es);
 				ExplainPropertyFloat("Actual Loops", NULL, nloops, 0, es);
 			}
 
diff --git a/src/test/regress/expected/partition_prune.out b/src/test/regress/expected/partition_prune.out
index 7555764c77..002e5cc33d 100644
--- a/src/test/regress/expected/partition_prune.out
+++ b/src/test/regress/expected/partition_prune.out
@@ -2635,14 +2635,14 @@ order by tbl1.col1, tprt.col1;
 insert into tbl1 values (1001), (1010), (1011);
 explain (analyze, costs off, summary off, timing off)
 select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1;
-                                QUERY PLAN                                
---------------------------------------------------------------------------
+                                 QUERY PLAN                                  
+-----------------------------------------------------------------------------
  Nested Loop (actual rows=23 loops=1)
    ->  Seq Scan on tbl1 (actual rows=5 loops=1)
-   ->  Append (actual rows=5 loops=5)
+   ->  Append (actual rows=4.60 loops=5)
          ->  Index Scan using tprt1_idx on tprt_1 (actual rows=2 loops=5)
                Index Cond: (col1 < tbl1.col1)
-         ->  Index Scan using tprt2_idx on tprt_2 (actual rows=3 loops=4)
+         ->  Index Scan using tprt2_idx on tprt_2 (actual rows=2.75 loops=4)
                Index Cond: (col1 < tbl1.col1)
          ->  Index Scan using tprt3_idx on tprt_3 (actual rows=1 loops=2)
                Index Cond: (col1 < tbl1.col1)
@@ -2656,16 +2656,16 @@ select * from tbl1 inner join tprt on tbl1.col1 > tprt.col1;
 
 explain (analyze, costs off, summary off, timing off)
 select * from tbl1 inner join tprt on tbl1.col1 = tprt.col1;
-                                QUERY PLAN                                
---------------------------------------------------------------------------
+                                 QUERY PLAN                                  
+-----------------------------------------------------------------------------
  Nested Loop (actual rows=3 loops=1)
    ->  Seq Scan on tbl1 (actual rows=5 loops=1)
-   ->  Append (actual rows=1 loops=5)
+   ->  Append (actual rows=0.60 loops=5)
          ->  Index Scan using tprt1_idx on tprt_1 (never executed)
                Index Cond: (col1 = tbl1.col1)
          ->  Index Scan using tprt2_idx on tprt_2 (actual rows=1 loops=2)
                Index Cond: (col1 = tbl1.col1)
-         ->  Index Scan using tprt3_idx on tprt_3 (actual rows=0 loops=3)
+         ->  Index Scan using tprt3_idx on tprt_3 (actual rows=0.33 loops=3)
                Index Cond: (col1 = tbl1.col1)
          ->  Index Scan using tprt4_idx on tprt_4 (never executed)
                Index Cond: (col1 = tbl1.col1)
