I have table as below
ID NAME AGE ZIPCODE
1 A 29 321345
2 B 25 321375
....
and so on about 40K records.
I want to fetch distinct zipcodes only upto 4 digits.
like 3213* include both (321345 || 321375).
So is there any similar clause as GROUP BY for this?
If only distinct zipcodes(4-digit) is need, use this:
SELECT DISTINCT LEFT(zipcodes, 4) ZIPCODE_4_DIGIT FROM tbl
If the frequency is also needed, use another:
SELECT LEFT(zipcodes, 4) ZIPCODE_4_DIGIT, COUNT(1) FREQUENCY
FROM tbl
GROUP BY ZIPCODE_4_DIGIT;
Related
This is my persons table:
neighborhood birthyear
a 1958
a 1959
b 1970
c 1980
I'd like to get the COUNT of people in an age group within every neighborhood. For example, if I wanted to get everyone under the age of 18, I would get:
neighborhood count
a 0
b 0
c 0
If I wanted to get everyone over 50, I'd get
neighborhood count
a 2
b 0
c 0
I tried
SELECT neighborhood, COUNT(*)
FROM persons
WHERE YEAR(NOW()) - persons.birthyear < 18
GROUP BY neighborhood;
but this gives me 0 rows, when instead I want 3 rows with distinct neighborhoods and 0 count for each. How would I accomplish this?
You can use conditional aggregation:
SELECT neighborhood, SUM(YEAR(NOW()) - p.birthyear) as under_18,
SUM(YEAR(NOW()) - p.birthyear BETWEEN 34 AND 42) as age_34_42
FROM persons p
GROUP BY neighborhood;
I think that if the count is 0, the row doesn't appear.
Your code seems correct to me, if you try it on the example with age 50, it should give you one row whith the expected line (neighborhood:a,count:2)
I would recommend using a sub query:
SELECT
count(*) [group-by-count-greater-than-ten]
FROM
(
SELECT
columnFoo,
count(*) cnt
FROM barTable
WHERE columnBaz = "barbaz"
GROUP BY columnFoo
)
AS subQuery
WHERE cnt > 10
In the above, the subquery return result set is being used by the main query as any other table.
The column cnt is no longer seen by the main query as a computed field and does not have to reference the count() function.
However, inside the subquery running a where clause or a having clause that must look at the alias cnt column, the count() function would have to be referenced as referencing cnt in the subquery would throw an error.
In your case using a subquery would look something like this.
SELECT
neighborhood,
age,
count(*) as cnt
FROM
(
SELECT
*,
(YEAR(NOW()) - birthyear) as age
FROM PERSONS
) as WithAge
WHERE age < 18
GROUP BY neighborhood, age
I have table like this
enter image description here
I need to get the data only whose age > 10, along with that i need to get the total number of records present in the table. ie. in this example it is 4 records. what i need is in single query i need to get the total number of records present in table and columns which i query.
Query will be somewhat like
SELECT ID, NAME, count(TOTAL NUMBER OF RECORDS IN TABLE) as Count from MYTABLE WHERE AGE > 10
Any idea about this ?
You can use a subquery in the FROM clause:
SELECT ID, NAME, c.cnt as Count
FROM MYTABLE CROSS JOIN
(SELECT COUNT(*) as cnt FROM MYTABLE) c
WHERE AGE > 10 ;
Both databases support window functions, but they are not really helpful here, because the count is not filtered in the same way as the outer query. If you do want the filter for both, then in the most recent versions you can do:
SELECT ID, NAME, COUNT(*) OVER () as cnt
FROM MYTABLE
WHERE AGE > 10 ;
You can try below - using scalar subquery
SELECT ID, NAME, age,(select count(*) from mytable WHERE AGE > 10) as Count
from MYTABLE
WHERE AGE > 10
I have a table with about 3 million rows that consists of cities, the countries in which the city lies and some other data.
I want to retrieve for example limited rows where the name of the city starts with a certain string but list those that lie in a specific country first.
I tried to order them by country <> "us" which is very slow as the server has to sort all found rows before applying the limit.
Now I came up with the following statement:
(SELECT * FROM cities WHERE city LIKE "ab%" AND country = "at" LIMIT 5)
UNION
(SELECT * FROM cities WHERE city LIKE "ab%" LIMIT 5)
LIMIT 5
It is very fast with any prefix length but it looks kinda dirty.
Is there a more efficient way to do this?
select top 5 *
, case when country = 'ab' then 1
else 0 end as rnk
from cities
where lower(city) like 'ab%'
or country = 'ab'
order by rnk desc;
I can't seem to find a suitable solution for the following (probably an age old) problem so hoping someone can shed some light. I need to return 1 distinct column along with other non distinct columns in mySQL.
I have the following table in mySQL:
id name destination rating country
----------------------------------------------------
1 James Barbados 5 WI
2 Andrew Antigua 6 WI
3 James Barbados 3 WI
4 Declan Trinidad 2 WI
5 Steve Barbados 4 WI
6 Declan Trinidad 3 WI
I would like SQL statement to return the DISTINCT name along with the destination, rating based on country.
id name destination rating country
----------------------------------------------------
1 James Barbados 5 WI
2 Andrew Antigua 6 WI
4 Declan Trinidad 2 WI
5 Steve Barbados 4 WI
As you can see, James and Declan have different ratings, but the same name, so they are returned only once.
The following query returns all rows because the ratings are different. Is there anyway I can return the above result set?
SELECT (distinct name), destination, rating
FROM table
WHERE country = 'WI'
ORDER BY id
Using a subquery, you can get the highest id for each name, then select the rest of the rows based on that:
SELECT * FROM table
WHERE id IN (
SELECT MAX(id) FROM table GROUP BY name
)
If you'd prefer, use MIN(id) to get the first record for each name instead of the last.
It can also be done with an INNER JOIN against the subquery. For this purpose the performance should be similar, and sometimes you need to join on two columns from the subquery.
SELECT
table.*
FROM
table
INNER JOIN (
SELECT MAX(id) AS id FROM table GROUP BY name
) maxid ON table.id = maxid.id
The problem is that distinct works across the entire return set and not just the first field. Otherwise MySQL wouldn't know what record to return. So, you want to have some sort of group function on rating, whether MAX, MIN, GROUP_CONCAT, AVG, or several other functions.
Michael has already posted a good answer, so I'm not going to re-write the query.
I agree with #rcdmk . Using a DEPENDENT subquery can kill performance, GROUP BY seems more suitable provided that you have already INDEXed the country field and only a few rows will reach the server. Rewriting the query giben by #rcdmk , I added the ORDER BY NULL clause to suppress the implicit ordering by GROUP BY, to make it a little faster:
SELECT MIN(id) as id, name, destination as rating, country
FROM table WHERE country = 'WI'
GROUP BY name, destination ORDER BY NULL
You can do a GROUP BY clause:
SELECT MIN(id) AS id, name, destination, AVG(rating) AS rating, country
FROM TABLE_NAME
GROUP BY name, destination, country
This query would perform better in large datasets than the subquery alternatives and it can be easier to read as well.
My current query looks like this:
SELECT DISTINCT (member), count( UID ) AS numUID
FROM memberdata
GROUP BY Member
ORDER BY count( UID ) DESC
What I get back, looks a lot like this:
A name 1 175
A name 2 38
A name 3 37
A name 4 36
A name 5 36
What I want to do now is get the count of numUID, in the above example I may get a result like:
**numUID** **COUNT**
175 1
38 1
37 1
36 2
I've searched far and wide, but I can't seem to get the information I need to put this query together properly. Any help would be appreciated.
Thanks,
Use a subselect and another GROUP BY:
SELECT numUID, COUNT(*)
FROM (
SELECT member, count(UID) AS numUID
FROM memberdata
GROUP BY Member
) T1
GROUP BY numUID
I should also warn you that you are also misusing DISTINCT. When you use DISTINCT it always looks at the entire row. Writing DISTINCT(x) , y is exactly the same as DISTINCT x, y. When you use GROUP BY it is guaranteed that you will only get one row per group. There is no need to use DISTINCT here.