Sql Query, Select distinct rows where not null - mysql

I have a question:
So I have the following data in a table"
id name city state phone price
234 Kevin Chicago IL 5555555555 550
234 Kevin Chicago IL 5555555555 NULL
234 Kevin Chicago IL 55555 NULL
234 Kevin Chicago IL NULL NULL
People have loaded data into a database and it is showing up like this because of character restrictions for each line...
So how can I tell my distinct query to get the most from each one..I just want this row returned:
234 Kevin Chicago IL 5555555555 550
And I cant do "where all rows are not null etc" because the last row can always be null too it depends.
Thanks a lot of your help!

Depending on what "the most" means exactly and depending on the data types of phone and price, this could be your query:
Edit: generalize query, get phone & price per person.
SELECT id, name, city, state, max(phone) AS phone, max(price) AS price
FROM tbl
GROUP BY id, name, city, state;
phone and price can come from different rows this way.
The manual on aggregate functions:
Unless otherwise stated, group functions ignore NULL values.
So, IFNULL or COALESCE are not required here.

try this
SELECT
ID,
MAX (IFNULL (NAME, ' ')) AS NAME,
MAX (IFNULL (CITY, ' ')) AS CITY,
MAX (IFNULL (STATE, ' ')) AS STATE,
MAX (IFNULL (PHONE, ' ')) AS PHONE,
MAX (IFNULL (PRICE, ' ')) AS PRICE
FROM MyTable
GROUP BY ID
The above gives you for each the "max" of each column - this can lead to content from different rows being combined...

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

Saving a COUNT column appearance while printing each row in the table

So there is a question I have not been able to find an answer to. Say you want to print each row in a table like the following:
ID | Name | Location
----+------+----------
1 | Adam | New York
2 | Eva | London
3 | Jon | New York
which would give the result
1 Adam New York
2 Eva London
3 Jon New York
Say that I at the same time would like to count the number of occurrences someone lives in a specific city, and save that value for printing after I've iterated through the table; is that possible? For example, printing the following:
1 Adam New York
2 Eva London
3 Jon New York
Inhabitants in New York: 2
Inhabitants in London: 1
Is this possible or would you have to iterate through the entire table twice by grouping by Location the second time, and counting those?
EDIT:
To clarify, I know I can solve it by calling:
SELECT * FROM table;
SELECT CONCAT('Inhabitants in ', Location, ': ', COUNT(ID))
FROM table
GROUP BY Location;
But now I am iterating through it twice. Is it possible to do it in only one iteration?
Generally speaking, yes, displaying every row from the table and displaying aggregated data is two separate tasks which should be handled by application, not by the database.
You have the option to run two queries - a plain select * from T, and select location, count(*) from T group by location, and displaying results sequentially. You also have the option to run only a select * from T one, and count the rows within your application, since you're displaying all rows anyway: use any dictionary-like structure your app language provides, with location string for key and running total integer for value.
If you're keen on keeping it a single query, check out WITH ROLLUP clause - https://dev.mysql.com/doc/refman/8.0/en/group-by-modifiers.html. This would certainly be an unusual way of using it, but if you group by location, id and then tamper with results a little, you can get what you want.
select if(id is null, CONCAT('Inhabitants in ', location, ': ', cnt), concat(id, ' ', name, ' ', location))
from
(
select id, location, name, count(*) cnt
from t
where location is not null
group by location, id with rollup
) q
where location is not null
order by id is null, id asc;
Though the performance could be questionable, compared to two plain queries; you should experiment or check with EXPLAIN.
Try below query, use subquery
select concat(concat(concat('Inhabitants in ',location),':'),total)
from
(select location, count(id) total
from tablename group by location)a

MySql query that aggregate and separe with comma

I need to do a query that return all my contact name separeted by comma's when they belong the same Group. I know how to do this in SQL Server using STUFF function, but how can I do the same in MySQL ?
Table: Group
Group_Id Description
1 New Group
2 Birthday
Table: Contacts
ID Name Surname Group_Id
1 Charlan Alves 1
2 Lucas Germano 2
3 Junior dos Santos 1
What I Expect
Group_Id Name
1 Charlan Alves, Junior dos Santos
2 Lucas Germano
Use GROUP_CONCAT():
SELECT
Group_Id,
GROUP_CONCAT(CONCAT(Name, ' ', Surname)) AS group_name
FROM
Contacts
GROUP BY
Group_Id
Note, that default separator is , (without space after comma). You may wish to add space after comma by specifying SEPARATOR ', '

MySQL Query to display records from table

I have a query.I have table with two columns country and state.I want to display columns in following format
Country State
----------- ---------
India Delhi
Bangalore
Kolkata
Mumbai
USA California
Florida
Las Vegas
Virginia
It means "India" just appear one time in country column and and repeated values would come as blank value in country column when i select country and state from table.
Thanks in advance
Presentation is usually if not always better done outside of SQL so I'd recommend doing this in whatever your presentation layer runs, but if it's a requirement for the query, you can do it using session variables;
SELECT Country, State FROM (
SELECT IF(Country=#country, '', Country) Country, State, #country := Country
FROM (SELECT Country, State FROM Table1 ORDER BY Country, State) dummy1,
(SELECT #country:='') dummy2
) dummy3;
An SQLfiddle to test with.
Just to show a (probably) better way, you can use this to get a list of states per country, and process it further in your presentation layer;
SELECT Country, GROUP_CONCAT(State) FROM Table1 GROUP BY Country;
Another SQLfiddle.
use pl/sql.Moreover your table would be voilating 5th normal form.

SQL Query to provide me with the total number

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;