SQL Query to provide me with the total number - mysql

I have a table with 3 columns
Column 0: auto inc index
Column 1: Person's Gener
Column 2: The STATE the person lives in (US States and Puerto Rico)
I want to run a query that tells me how many MEN are in each state
so the output would list all 50 states (in 1 column) and the second would be a number to determine the number of MEN in that state
Alaska 1000
New York 85000
(the figures above aren't accurate but i'm illustrating what I am looking for)
Thanks

You need to use a GROUP BY clause and the COUNT aggregate function.
SELECT State, COUNT(*) AS NumberOfMen
FROM your_table
WHERE Gender = 'M'
GROUP BY State

try this
select STATE, count(*) as num from table_name where gender ='MALE' GROUP BY STATE;

Related

SSRS Row Group with non-aggregated measure column

I'm not finding any other questions exactly like mine, so it's time to ask.
I have an SSRS 2016 report. It's got a regional hierarchy (State, City, Location). And it's got one measure column that is a calculation performed in the stored procedure. Due to the nature of the calculation, the value of the calculation for a city must be performed independently in the stored procedure. It's not a simple aggregation of the Locations in the City, so it cannot simply be aggregated in the report. I need the report to expand and contract on the regional hierarchy columns, and to pull the measure values straight from the dataset with aggregating.
In other words
I have a dataset like this:
State City Location Measure
FL NULL NULL 25
FL Miami NULL 12
FL Miami Walmart 52
FL Miami Kmart 3
FL Orlando NULL 33
FL Orlando Sears 4
I need for the report to have collapsible rowgroups at the State and City levels, with Location being the "detail" level row group. But I need the value of Measure to be 12 for Miami, and not some aggregation of 2 & 3 (Walmart and Kmart).
I figure the approach must be either:
Use traditional row groups and do some kind of programming in the expression of the measure column for the two upper-level row groups, or
Don't put row groups on the tablix and do conditional formatting of the rows and some kind of programming in the toggle properties.
But in both cases, I'm not seeing anything I can do that SSRS will actually allow for the "some kind of programming" bit.
Is there a solution?
If you must do it in the report, I think you could use a table a FILTER out the NULL city and location values. When you need them you could do a Lookup to get the value from the dataset. This will lookup the Measure value for a City where the IIF will act as a filter for the NULL value - if there is a location the City will have an X0 added and won't match the Lookup City.
=Lookup(Fields!City.Value, Fields!City.Value & IIF(ISNOTHINGFields!Location.Value), "", "x0"), Fields!Measure.Value, "Dataset1")
If you can put your current results in a temp table, a better way would be to add the totals as seperate fields in the query.
SELECT 'FL' AS State, NULL AS City , NULL as Location, 25 as Measure
INTO #TABLE
UNION
SELECT 'FL' AS State, 'Miami' AS City , NULL AS Location, 12 as Measure
UNION
SELECT 'FL' AS State, 'Miami' AS City , 'Walmart' as Location, 52 as Measure
UNION
SELECT 'FL' AS State, 'Miami' AS City , 'Kmart' as Location, 3 as Measure
UNION
SELECT 'FL' AS State, 'Orlando' AS City , null as Location, 33 as Measure
UNION
SELECT 'FL' AS State, 'Orlando' AS City , 'Sears' as Location, 4 as Measure
--DROP TABLE #TABLE
SELECT T.*, T_S.Measure AS STATE_MEASURE, T_C.Measure AS CITY_MEASURE
FROM #TABLE T
LEFT JOIN #TABLE T_S ON T.State = T_S.State AND T_S.City IS NULL
LEFT JOIN #TABLE T_C ON T.State = T_C.State AND T_C.City = T.City AND T_C.Location IS NULL
WHERE T.City IS NOT NULL AND T.Location IS NOT NULL
This will let you just have the recordsd you need with the additional comlumns for the summary data.
Group on state and city and don't use SUM() for your Measure column
Your layout could be like the one below

MySQL: Conditional MIN() with GROUP BY

I have this table called times where I record race information for a racing game:
race_id map name time
30509 desert Peter 12.68
30510 desert Jakob 10.72
30511 desert Peter 18.4
30512 jungle Peter 39.909
30513 jungle Peter 39.84
30514 desert Harry 16.129
30515 space Harry 774.765
30516 jungle Jonas 46.047
30517 city Jonas 23.54
30518 city Jonas 23.13
30519 desert Mike 22.9
30520 space Fred 174.244
I have two questions. How would I best go about:
Finding the lowest time (world record) on a given map?
I have tried this query:
SELECT *, MIN(time) FROM times WHERE map = 'desert';
This yields a seemingly incorrect arbitrary row with an added column called MIN(time) where the correct lowest time is.
Finding the lowest time on all maps, but only if it's done by a certain player (find all world records by given player)?
For this I have tried this query:
SELECT *, MIN(time) FROM times WHERE name = 'Peter' GROUP BY map;
This seems to only return the first row by the given name for each map, regardless if it's the lowest time or not.
I'm fairly new to SQL(MySQL), so I might be missing something obvious here. I've been looking around for quite a while now, and any help would be greatly appreciated. Thanks!
if you want the fastest performance on a given race, you can just order by and limit:
select *
from times
where map = 'desert'
order by time limit 1
On the other hand, if you want all race records for a given user, then it is a bit different. One option uses a correlated subquery for filtering:
select t.*
from times t
where
name = 'Peter'
and time = (select min(t1.time) from times t1 where t1.map = t.map)
Finding the lowest time (world record) on a given map
SELECT `time`
FROM times
WHERE map = #map
ORDER BY `time` ASC
LIMIT 1
Finding the lowest time on all maps, but only if it's done by a certain player (find all world records by given player)
SELECT `time`
FROM times
WHERE name = #name
ORDER BY `time` ASC
LIMIT 1

Query to find count of tagging for item in column A to item in column B

I need to find out count of different entries for same entry in a column (State - North Dakota) to another column (Onshore, offshore) in SQL. In the attached sample - Number of mismatch is 1 (North Dakota - Offshore). Many thanks for any help.
.
You seem to want to count the number of states that have more than 1 distinct terrain. If so, you can use two levels of aggregation:
select count(*) no_mismatches
from (select state from mytable group by state having min(state) <> max(state)) t
Do you want count(distinct)?
select state, count(distinct terrain)
from t
group by state;

MySQL Multiple query with a bit of logic

I have a Users table with these values (stripped down for the example):
Name
City
County
StateProvince
Country
Continent
Strength
Endurance
Intelligence
I basically want a query that returns the highest stat by region for yourself. If you have the highest Strength (67) in the country, highest Endurance (59) in your City, and not the highest Intelligence anywhere, I'd like a 2 row result of:
('Strength', 67, 'Country', 'United States')
('Endurance', 59, 'City', 'Redmond')
Note that if you have the highest Strength in the country, you will also have the highest strength in the state/province, county, and city (but I'd like those not to be returned in the result). I can do this all using multiple SELECT queries, however, I'd like to know how to do this in one single query for efficiency (or if that's even a good idea?). I'd imagine the logic would go something like (pseudo code):
(SELECT FROM Users ORDERBY Strength WHERE Country = 'MyCountry' LIMIT 1) IF Name != 'Me' (SELECT FROM Users ORDERBY Strength WHERE StateProvince = 'MyState' LIMIT 1) ... and so on
Furthermore, the above would also need to work with Endurance and Intelligence. Thanks!
Check this link MySQL control-flow-functions
SELECT CASE 1 WHEN 1 THEN 'one' WHEN 2 THEN 'two' ELSE 'more' END;

How to prioritize a LIKE query select based on string position in field?

I am attempting to query a table for a limited resultset in order to populate an autocomplete field in javascript. I am, therefore, using a LIKE operator with the partial string entered.
If I have, for example, a table such as:
tblPlaces
id country
1 Balanca
2 Cameroon
3 Canada
4 Cape Verde
5 Denmark
For the sake of this example, let's say I want two rows returning - and yeah, for this example, I made up a country there ;) I want to prioritize any instance where a partial string is matched at the beginning of country. The query I began using, therefore is:
SELECT id, country FROM tblPlaces WHERE country LIKE 'ca%' LIMIT 2
This returned 'Cameroon' and 'Canada' as expected. However, in instances where there are no two names in which the string is matched at the beginning of a word (such as 'de'), I want it to look elsewhere in the word. So I revised the query to become
SELECT id, country FROM tblPlaces WHERE country LIKE '%ca%' LIMIT 2
This then returned 'Cape Verde' and 'Denmark', but in doing so broke my original search for 'ca', which now returns 'Balanca' and 'Cameroon'.
So, my question is, how to go about this using a single query that will prioritize a match at the start of a word (perhaps I need to use REGEXP?) I am assuming also that if the 'country' column is indexed, these matches will at least be returned with subsequent alphabetical priority (i.e. Cameroon before Canada etc).
If you mean to prioritize matches that are Exactly at the start...
SELECT id, country
FROM tblPlaces
WHERE country LIKE '%ca%'
ORDER BY CASE WHEN country LIKE 'ca%' THEN 0 ELSE 1 END, country
LIMIT 2
EDIT
More generic and possibly faster (Assuming "closer to the start the 'better' the match")...
SELECT id, country
FROM tblPlaces
WHERE country LIKE '%ca%'
ORDER BY INSTR(country, 'ca'), country
LIMIT 2