9 min readecommerce metricsecommerce analyticsWooCommercecatalogue

The 6 store metrics that actually move money

Measured today on a real WooCommerce store with 5,621 products: 255 of them take half the clicks. That's 4.5% of the catalogue. And 4,163 products got none at all in 31 days. Here are the six metrics that actually change decisions — concentration, dead catalogue, demand with no stock — with the SQL to pull each one from your own database today.

Almost all store analytics measure the same things: visits, sessions, bounce rate, time on page. Numbers that go up and down and that, honestly, decide nothing. Nobody has ever restocked a product because average session time dropped twelve seconds.

These six are different. All six can be pulled today from your own database, with SQL, with nothing to install. And all six end in a concrete decision: what you restock, what you stop buying, who you write to.

I'll start with the one that surprised me most when I measured it.

The measurement

Everything here comes from a real store: a WooCommerce collectibles shop, from 18 August to 17 September 2026 (31 days), measured today.

Products in the catalogue 5,621
Products in stock 1,644 (29.2%)
Searches 50,627
Sessions that searched 11,380
Clicks on results 17,261

1. Concentration: how many products take half your demand

The answer in this store: 255. Out of 5,621 products, 255 account for half of the 17,261 clicks. That's 4.5% of the catalogue. With 663 products you reach 80%.

And at the other end: 4,163 products got no clicks at all in 31 days.

That last number needs a caveat, and the caveat is half the story: of the 5,621 products, only 1,644 are in stock, and this store's search doesn't show sold-out items. So much of that catalogue isn't uninteresting — it simply doesn't exist as far as the customer is concerned. Counted only over what is actually for sale, 1,423 of 1,644 products (86.6%) got at least one click, and the 255 that make up half the demand are 15.5% of what's available.

Both readings matter, and they're different:

  • Over the whole catalogue, it tells you how much dead weight you're carrying. 3,977 sold-out pages taking up room in your database, your sitemap and your head.
  • Over what's in stock, it tells you where your money really is. A sixth of your available inventory takes half the attention.

The decision that comes out of this is a buying one: those 255 never run out, and everything else gets a second look before you reorder.

To pull it from your sales rather than your clicks, WooCommerce already stores what you need in its Analytics tables:

-- How many products make up half your revenue, last 90 days
WITH sales AS (
  SELECT product_id, SUM(product_net_revenue) AS revenue
  FROM wp_wc_order_product_lookup
  WHERE date_created >= DATE_SUB(NOW(), INTERVAL 90 DAY)
  GROUP BY product_id
),
ranked AS (
  SELECT product_id, revenue,
         SUM(revenue)  OVER (ORDER BY revenue DESC) AS running,
         SUM(revenue)  OVER () AS total,
         ROW_NUMBER()  OVER (ORDER BY revenue DESC) AS rank_pos
  FROM sales
)
SELECT MIN(rank_pos) AS products_making_half
FROM ranked
WHERE running >= total * 0.5;

(wp_wc_order_product_lookup is a WooCommerce Analytics table; it has existed since WooCommerce 4.0. Swap wp_ for your prefix. If you're on MySQL 5.7, window functions don't exist: there's a version without them at the end.)

2. Dead catalogue: what hasn't sold a single unit

The hard version of the previous metric. Not "sells little": zero.

-- Published products that haven't sold a single unit in 180 days
SELECT p.ID, p.post_title
FROM wp_posts p
LEFT JOIN wp_wc_order_product_lookup l
  ON l.product_id = p.ID
 AND l.date_created >= DATE_SUB(NOW(), INTERVAL 180 DAY)
WHERE p.post_type = 'product'
  AND p.post_status = 'publish'
  AND l.product_id IS NULL
ORDER BY p.post_date ASC;

Sorted by age, because a product from last week with no sales says nothing and one from two years ago does.

That list has three kinds of product in it, and it's worth separating them before deciding anything: the one nobody wants, the one people do want but can't find because it's named differently from how they search for it, and the one that never even gets shown. The last two aren't a catalogue problem, they're a search problem, and they're fixed without touching inventory. That's the difference between liquidating good stock and fixing a search.

3. Demand with no stock: what people ask for and you don't have

This is the one that shows up in no dashboard, and the one that moves the most money of the six.

In this store, over 31 days, 35 sold-out products got 356 clicks. People who searched for something, saw it, opened the page and found "out of stock". The most wanted, an item priced at 80 €, had 54 people doing exactly that.

54 people interested in one specific 80 € product is a buying decision, not a report. And it appears nowhere: it isn't in your sales (it didn't sell), and in your traffic it's diluted among 11,380 other sessions.

There are two ways to lose this demand, and both are expensive:

  1. Show the sold-out product. At least you find out, if you measure it. And you can add a "notify me when it's back" box, which turns that click into an email address.
  2. Hide sold-out items. Cleaner for the customer, but then the search returns zero results and there's no trace that anyone asked. If your search hides out-of-stock items, you need its zero-result log, or that demand is invisible.

To measure it you need your search log with the number of results for each query. If you don't have one, the Google Analytics article has the 30-line mu-plugin that stores it, with no cookies and no personal data. With that table, the query is:

-- Most searched terms that return zero results, last 30 days
SELECT termino, COUNT(*) AS times
FROM wp_wr_busquedas
WHERE resultados = 0
  AND creado >= DATE_SUB(UTC_TIMESTAMP(), INTERVAL 30 DAY)
GROUP BY termino
ORDER BY times DESC
LIMIT 50;

4. Sessions that search and click nothing

Of the 11,380 sessions that searched for something, 6,072 clicked no result at all. That's 53.4%.

More than half the people who told you in their own words what they wanted left without opening anything you showed them.

This number is a diagnosis, not a verdict. It goes up for three different reasons, and you need to know which is yours:

  • What they wanted wasn't there. Fixed by buying it, or by telling them when it arrives.
  • It was there, but they didn't recognise it in the results: bad title, no photo, or buried in position 15.
  • They searched half-heartedly. Typed two letters, glanced at the list and carried on browsing. This inflates the number and isn't a problem.

To tell them apart, read this metric next to the following one: if people search four times a session and click nothing, they weren't just browsing.

In this store the average was 4.4 searches per session, and 3,286 sessions (28.9%) searched only once. The rest kept trying.

5. Average order value, but looking at the shape rather than the mean

Average order value on its own misleads, because a store with lots of 20 € orders and a few 400 € ones gives the same average as a store where everyone spends 60 €, and those aren't the same business and aren't run the same way.

Pull the average and the bands:

-- Average order value and spread by band, last 90 days
SELECT
  COUNT(*)                     AS orders,
  ROUND(AVG(total_sales), 2)   AS average_order,
  SUM(total_sales < 25)        AS under_25,
  SUM(total_sales >= 25  AND total_sales < 60)  AS from_25_to_60,
  SUM(total_sales >= 60  AND total_sales < 150) AS from_60_to_150,
  SUM(total_sales >= 150)      AS over_150
FROM wp_wc_order_stats
WHERE status IN ('wc-completed', 'wc-processing')
  AND date_created >= DATE_SUB(NOW(), INTERVAL 90 DAY);

If the top band is small in order count but large in revenue, that's your real customer, and it probably isn't the one you're talking to on your homepage.

6. Repeat customers

The last one, and the cheapest to move. A customer who already bought from you doesn't need you to pay for the advertising twice.

-- What share of your customers has bought more than once (last 12 months)
SELECT
  COUNT(*)                                    AS customers,
  SUM(orders > 1)                             AS repeat_customers,
  ROUND(100 * SUM(orders > 1) / COUNT(*), 1)  AS pct_repeat,
  ROUND(AVG(spent), 2)                        AS average_spend_per_customer
FROM (
  SELECT customer_id, COUNT(*) AS orders, SUM(total_sales) AS spent
  FROM wp_wc_order_stats
  WHERE status IN ('wc-completed', 'wc-processing')
    AND date_created >= DATE_SUB(NOW(), INTERVAL 12 MONTH)
    AND customer_id > 0
  GROUP BY customer_id
) AS c;

If the repeat share is low, metric 3 is your next stop: demand with no stock is the most trivial and most common reason someone doesn't come back. They came, it wasn't there, they didn't return.

If your MySQL is old

Window functions (SUM() OVER (...)) need MySQL 8.0 or MariaDB 10.2. If your hosting is behind, metric 1 comes out in two steps:

-- Step 1: the total
SELECT SUM(product_net_revenue) AS total
FROM wp_wc_order_product_lookup
WHERE date_created >= DATE_SUB(NOW(), INTERVAL 90 DAY);

-- Step 2: products high to low, and you count down by hand to half the total
SELECT product_id, SUM(product_net_revenue) AS revenue
FROM wp_wc_order_product_lookup
WHERE date_created >= DATE_SUB(NOW(), INTERVAL 90 DAY)
GROUP BY product_id
ORDER BY revenue DESC
LIMIT 300;

In order, what I'd do:

  1. Pull metric 1 today. It takes a minute and tells you how many products actually hold up your store. It's almost always far fewer than you think.
  2. Cross the dead-catalogue list (metric 2) with your searches. What doesn't sell but does get searched isn't a bad product: it's a product that can't be found.
  3. Set up the search log if you don't have one. Without it, metrics 3 and 4 don't exist, and they're the two that move the most money.
  4. Add a restock notification to the sold-out pages people ask for most. 54 clicks on an 80 € product are 54 email addresses you could have.

The first four metrics measure what people are asking you for. Two of them lean on the search, because it's the one place in a store where the customer writes what they want in their own words. If you want to see why, there's the guide on how to choose an ecommerce search, with the price of each option checked. And the numbers in this article come from WildRock, which logs every search, what was shown and what was clicked.

Is your store losing sales to searches that find nothing?

WildRock adds a search to your WooCommerce that understands what shoppers mean, and tells you in euros how much it generates. Free plugin, no code.