简体   繁体   中英

How do I count values I've replaced in a SELECT query?

I'm trying to design a query that will allow me to count matching postcodes for customer orders, but I don't know how to nest function calls to accomplish that. This is what I have;

SELECT * FROM `xcart_orders` WHERE COUNT(REPLACE(s_zipcode, ' ', '')) > 2

I know this is wrong, because you can't nest aggregates. So how would I accomplish this? I'm not sure how to phrase the question to find the relevant answer. Ideally I would also like to replace character case using UPPER or UCASE to count matching values regardless of both case and whitespace, but I don't want to complicate my broken query any further.

Once I understand the principle of nesting functions calls, hopefully that will also show me how to chain them, but if that requires a different syntax, I would prefer the answer to show how to nest the functions COUNT > UPPER > REPLACE.

Here's an example;

IM2 6RB
im2 6rb
IM26RB
JE4 8PJ
sa626uf
64295
IM2 6RB
SA62 6UF
64295

These are postcodes in my database table. I want to count how many times a postcode occurs, and return results from the table where any postcode occurs more than once. But to get accurate matches, I need to ignore white space and capitalisation.

I want to return the all the rows, or specific fields from rows, where the same postcode is used more than once. So essentially be able to display which rows in the database use the same postcode as at least one other row.

Try this:

SELECT *
FROM `xcart_orders`
INNER JOIN ( 
    SELECT REPLACE(UPPER(s_zipcode), ' ', '') as Zip 
    FROM `xcart_orders`
    GROUP BY REPLACE(UPPER(s_zipcode), ' ', '')
    HAVING COUNT(REPLACE(UPPER(s_zipcode), ' ', '')) > 1
) XXX ON (REPLACE(UPPER(s_zipcode), ' ', '') = XXX.Zip)

See Demo here .

It's not clear to me yet, what you want to do exactly, but here's a first try to answer.

The order of operations in a query is roughly

  1. FROM
  2. WHERE
  3. GROUP BY
  4. HAVING
  5. ORDER BY
  6. SELECT

Aggregate functions like COUNT() can therefore not be used in the WHERE clause.
When you don't specify a GROUP BY clause, the aggregate function is applied to the whole dataset and you end up with only one row in your result set.

You seem to want to select only those rows, where you had to replace a whitespace three times. You can't use COUNT() for this, as it's used to count rows, not anything else.

You can however check, if the lenght after replacing is reduced by 3 characters.

SELECT * FROM `xcart_orders` 
WHERE CHAR_LENGTH(s_zipcode) - CHAR_LENGTH(REPLACE(s_zipcode, ' ', '')) > 2;

UPDATE (after question edit):

This will get you the duplicates.

SELECT * 
FROM xcart_orders xo
INNER JOIN (
    SELECT REPLACE(UPPER(s_zipcode), ' ', '') as zip
    FROM xcart_orders
    GROUP BY REPLACE(UPPER(s_zipcode), ' ', '')
    HAVING COUNT(*) > 1
) sq ON UPPER(REPLACE(xo.s_zipcode), ' ', '')) = sq.zip;

You could do something like this:

SELECT count(*) 
FROM `xcart_orders` 
WHERE 
(length(s_zipcode)-length(REPLACE(s_zipcode,' ', '')))/length(' ') > 0

Here is an example: http://sqlfiddle.com/#!2/e7d2c/1/0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM