Google reviews to Redshift

Redshift already holds the takings, the rota and the footfall. The one thing it does not hold is what the customer said, and that is the column that explains the other three.

Reviews syncing in under five minutes • No demo required

Amazon Redshift analytics.google_reviews
Google Business Profile 61,482 rows
profile_name Kestrel Market Bellwood
2

Two tills staffed at five on a Friday and half the self-checkouts down

profile_name Kestrel Market Severn Park
5

Marisol walked me to the thing I could not find. Twice.

profile_name Kestrel Express Ashgrove
4

Fine for a quick shop, the queue actually moves

profile_name Kestrel Market Bellwood
1

Self-checkout froze again and nobody came over

26 stores loading into one table COPY 09:34
  • chewy
  • qonto
  • brevo
  • jins
  • filmin
  • lugg

The question is which store is behind its own peers

Google Business Profile gives you a rating per listing and the reviews under it. It will never tell you that eight of your urban stores sit within a tenth of 4.5 while the ninth sits at 3.6, because it cannot put those nine numbers beside each other. In Redshift that is a CTE and a window function.

The comparison that matters is against a peer group, not the chain. A 3.6 means little beside an estate average that mixes a high street store with a forecourt express. It means a great deal beside the seven stores of the same format.

The shape of the answer is the diagnosis. A price change reads as every store drifting together. A rota gap, a card reader that stopped working, a manager who left in March, reads as one store falling while its neighbours hold.

The follow up is a WHERE clause, because the review text is an ordinary column. Count the reviews mentioning the self-checkouts since March, split by store, and you have it before the regional meeting does.

Amazon Redshift Query editor
-- every store against its own format, not the chain average
WITH by_store AS (
  SELECT s.site_key, s.format, AVG(r.score) AS rating
  FROM   analytics.google_reviews r
  JOIN   ops.stores s USING (profile_name)
  WHERE  r.review_date >= '2026-03-01'
  GROUP BY 1, 2
)
SELECT site_key, format, ROUND(rating, 1) AS rating,
       ROUND(rating - AVG(rating)
             OVER (PARTITION BY format), 1) AS vs_peers
FROM by_store ORDER BY vs_peers
Results 5 of 26 stores
site_key rating vs_peers
BELLWOOD 3.6 -0.9
ASHGROVE 4.1 -0.3
DUNMORE 4.3 -0.2
KIRKHAM 4.5 0.0
SEVERN PARK 4.6 +0.1

The store arrives as a listing title, and you map it once

Reviewflowz creates one review profile per Google listing, so the store that earned a review is written onto every row rather than inferred from the text. It reaches the synced sheet as column B, headed Profile Name, and it is the listing title as Google holds it. A title, not a street address.

So you map it once. Declare it as a VARCHAR, put a profile_name column on your own store table beside it, and from then on it is an ordinary join key with an ordinary DISTKEY on it.

That one time step beats a location column we filled in for you, because the mapping is yours. Two listings Google keeps apart can point at one site key. A store renamed in April keeps the same key on both sides of the rename.

Addresses do exist in the product, and it would be wrong to imply otherwise. The OData feed carries a Locations entity set with the street line, the city, the postcode and the latitude and longitude. They are not in the sheet, so they reach Redshift the way your own store table does.

Amazon Redshift analytics.google_reviews
profile_name VARCHAR(255) Join key

Column B in the synced sheet. The Google listing title.

review_id
VARCHAR(64)
review_date
TIMESTAMP
score
SMALLINT
review_text
VARCHAR(65535)
language
VARCHAR(8)
tags
VARCHAR(1024)
link
VARCHAR(512)
DISTSTYLE KEY DISTKEY (profile_name) SORTKEY (review_date)

No reply column. The synced sheet does not carry one, so nothing downstream of it can.

How the rows actually reach Redshift

There is no Redshift destination inside Reviewflowz to click, and this page will not invent one. What you get, on every plan, is a Google Sheet in your own Drive that Reviewflowz keeps current, at :02 and :32 past every hour.

Redshift never reads that sheet where it sits. BigQuery does, which is why the BigQuery version of this page is one CREATE EXTERNAL TABLE and this one is not. Every road into Redshift runs through S3, and the shortest is Amazon AppFlow, which takes Google Sheets as a source and Redshift as a destination.

AppFlow inserts, it does not upsert, and the sheet corrects itself when a reviewer edits. So reload the table rather than appending to it, or write the export yourself and hand it to a COPY JOB with AUTO ON. Either way the bucket is yours and this is an afternoon, not a quarter.

One thing quietly makes the no-code road work. AppFlow binds a Sheets flow to the column headers it finds and breaks when they move. The Reviewflowz export header does not move: 28 columns, same order on every sync, by design.

Amazon Redshift Getting rows in No connector
A · No code runs as often as every minute
Google Sheets Sheet AppFlow Amazon Redshift Redshift

AppFlow reads the sheet and writes Redshift, staging through an S3 bucket you own. It inserts, it does not upsert, so you reload rather than append.

B · One job you write you own this step
Google Sheets Sheet export S3 Amazon Redshift Redshift

One COPY with a JOB, and each new file that lands is picked up on its own.

Amazon Redshift Run once
COPY analytics.google_reviews
FROM 's3://kestrel-lake/reviews/'
IAM_ROLE 'arn:aws:iam::4471...:role/redshift-copy'
FORMAT CSV IGNOREHEADER 1
JOB CREATE load_google_reviews AUTO ON;

BigQuery queries a Drive-backed sheet in place. Redshift never does, so every road above runs through a bucket you own.

Join it to what you already keep per store

Every operator with more than one site keeps a table with a row per store and per week: takings, rota hours against plan, footfall, the date of the last refit. Google reviews arrive tagged the same way, so putting the two together is a JOIN rather than a project.

That is where the numbers stop being interesting and start being useful. A rating beside sales per visit shows what a bad quarter at one store actually costs. The same rating beside rota hours shows whether the store everyone complains about is the store nobody staffed.

It also fixes the comparison for good. Join to your own segments, high street against retail park, refitted against waiting, and every store gets measured against the stores it actually resembles instead of against an average that describes none of them.

This is the whole reason to move Google reviews into a warehouse rather than read them in a tool. A review tool can only tell you about reviews. It cannot see the takings and never will be given them. Redshift already has them, which is why the review is the thing that should move.

Amazon Redshift

analytics.google_reviews

ops.store_week

ON site_key
from analytics ops
site_key rating rota_gap
BELLWOOD 3.6 -14%
ASHGROVE 4.1 -4%
DUNMORE 4.3 -1%
KIRKHAM 4.5 +2%
SEVERN PARK 4.6 +1%

site_key is yours. It reaches the reviews table through one mapping from the Google listing title, written once.

Six months of review text, one statement

The full review text is a VARCHAR column like any other, so the term you care about is an ILIKE and a GROUP BY instead of an afternoon of reading. Six months of Google reviews counted by store, for the word that keeps coming up, is one statement.

Reviewflowz detects each review’s language from the text itself and writes it as its own column, which is why a Spanish review left on a Texas listing still lands in the same table and still turns up in the same search once you widen the term.

Tags arrive filled in, so the themes are there before you write a classifier. Treat them as a starting point: the number a regional manager acts on is usually the count of reviews matching your own word, in your own vocabulary.

One warning about the date column, because it changes what you model. Google review volume tracks footfall, not a release schedule. It climbs on Friday, doubles on Saturday, and jumps for a fortnight after a local campaign. A monthly average sits above five of those days and under the other two, so compare like for like on day of week.

Amazon Redshift Query editor
-- six months of review text, one statement
SELECT s.site_key,
       COUNT(*) AS reviews,
       SUM(CASE WHEN r.review_text ILIKE '%self-checkout%'
                THEN 1 ELSE 0 END) AS mentions
FROM   analytics.google_reviews r
JOIN   ops.stores s USING (profile_name)
WHERE  r.review_date >= DATEADD(month, -6, CURRENT_DATE)
GROUP  BY 1
ORDER  BY mentions DESC
Results 5 of 26 stores in 1.2s
site_key reviews mentions share
BELLWOOD 214 61 29%
KIRKHAM 178 14 8%
SEVERN PARK 152 9 6%
DUNMORE 131 7 5%
ASHGROVE 96 5 5%

Redshift knows everything about the store except what the customer said

Set up in under five minutes. No demo required.

Is there a native Redshift connector?

Not from Reviewflowz, and it would be dishonest to imply one. What Reviewflowz gives you is a Google Sheet synced into your own Drive on every plan, plus the Review API and webhooks on Premium. AWS supplies the other half. Amazon AppFlow takes Google Sheets as a source and Redshift as a destination, staging through an S3 bucket you own, which is configuration rather than code. If you would rather own the pipeline, export the rows to S3 yourself and load them with a COPY JOB. Both are more work than the BigQuery version of this page, where BigQuery queries the sheet in place. Neither is more than an afternoon.

Does the store really land on every row?

Yes. Reviewflowz creates one review profile per Google listing, so every review row carries the listing it belongs to. It arrives as column B of the synced sheet, headed Profile Name, and it is the listing title as Google holds it rather than an id of yours. Map those titles onto your own site keys once when you create the table, and after that it is an ordinary join key.

How current is the table?

The sheet resyncs at :02 and :32 past every hour, so everything downstream can be scheduled against those two marks. AppFlow runs a scheduled flow as often as once a minute. A COPY JOB with AUTO ON loads each new file as it arrives rather than on a timer, and a COPY you run at 3am makes the table as current as 3am.

Which columns arrive?

The synced sheet has a fixed 28 column header and one row per review: the review id, the profile name, the platform, the title, the full text, the score, a link back, the review date, the detected language, the reviewer’s name, the tags, and the rest. There is no reply column and there are no per-platform tabs, so it maps onto one flat Redshift table with nothing to reshape.

Can we choose what flows out?

Yes. Pick which review profiles the sheet covers, and add a score filter if you want one, so the estate team gets every store while a support view gets one to three stars and nothing else.

Does the first load include our Google review history?

Yes, on a paid plan. One click seeds the sheet with every past Google review across your listings, so the trend line starts full rather than filling in over the next quarter. During the free trial new reviews arrive as they are posted, and the history loads once you subscribe.

What happens when a reviewer edits or deletes their review?

The row updates in place, keyed on the review id in column A, and when a review comes off your Google listing its row goes on the next sync. That has one consequence worth designing for. AppFlow inserts rather than upserts, and an append-only COPY keeps the old version alongside the corrected one. Reload the table, or upsert on review_id, and Redshift moves with the correction instead of holding a version of the truth Google no longer holds.

Does this work with Redshift Serverless?

Yes. Auto-copy is generally available on Redshift Serverless workgroups and on RA3 provisioned clusters, and AppFlow writes to either. Nothing on this page depends on which one you run.

Do I need a demo to get started?

No. Connect your Google Business Profile and the Google Sheet yourself in under five minutes. 14 day free trial, no credit card. The AWS half is yours to wire up, and it has the same shape as every other load you already run.