Grouping Mysql query contacts table by city - mysql

an easy one, its long time i do not use mysql queries so maybe someone can help me out with this nooby question, i have a contacts table, id, name, and city.. i want to get all the contacts listed as follows.
city 1
--------
contact1
contact2
contact3
city 2
--------
contact4
contact7
contact10
city 3
--------
contact5
contact6
contact8
I do not want to use any additional php coding, just get the sql result like this
city 1
-> contact 1
-> contact 2
-> contact 3
city 2
-> contact 4
-> contact 7
-> contact 10
...
then fill the result in a php object and do like this:
foreach (cities as city)
{
// code here
}
Thanks in advance

Use GROUP_CONCAT
SELECT city, GROUP_CONCAT(name)
FROM contacts
GROUP BY city

You just need to GROUP BY city column and use GROUP_CONCAT function in SELECT to get comma seprated list of names for each city.
SELECT city, GROUP_CONCAT(name) AS name
FROM contacts
GROUP BY city;

Related

compare values between comma in mysql

I have table like:
businesses:
id name tags
1 ken my, oh, abc
2 jen city, cle, dir
3 sen state, NY, irs
...
I want to create query like:
select * from businesses where name like 'ken' and tags = 'oh'
How can i get value between first and second comma?
select * from businesses where
name like 'ken' and FIND_IN_SET('oh',tags);

How to sort based on keyword first?

Here is a sample Database
First_name country
Andy US
Manu India
Paul Pakistan
Ramesh Pakistan
Rich India
So, what i want is to select all records from the above table and display according to name.
Like :-
I want to select person name to be display first whose country name is India and after US, Pakistan.
How can i perform this task in single SQL query ?
Update
I don't know how many Country are there.
Country the need to be display first will be input by the user.
Use a CASE statement to give each record a sortkey. 0 for a country match, 1 for a mismatch, so the desired country comes first.
select *
from mytable
order by case when country = #country then 0 else 1 end, first_name
May be something like this
Select * From Table1
Order By CASE WHEN country = 'INDIA' THEN 0
WHEN country = 'US' THEN 1
Esle 2
END;
Or You can use FIELD
Select * From Table1 Order By FIELD(country, 'India', 'US', 'Pakistan') ;
Use FIELD Function
Try this:
SELECT fitst_name, country
FROM tableA
ORDER BY FIELD(country, 'India', 'US', 'Pakistan'), fitst_name

how to have a Count when using Groupby?

I have got a column name country in which there are 3 entries which are shown below. In each countries i have set of people working in it in a different column. I want a count query which can count how people are working in each country in a single query.
country
________
India
America
China
try this:
SELECT country,COUNT(*)
FROM table
GROUP BY country;

MySQL query: use each result/row to regex and count another table

Not sure if this is possible. With two tables, one is country codes:
e.g.
id | code | country
1 .us United States
2 .ru Russia
And so on (about 200+ rows)
The other is URLs:
http//:example.gov.us
http://example.gov.ru/index.php
http://xyz.gov.us/test.html
And so on.
I don't know what URLs will come in, so I would have to grab each country code and somehow query the URLs for any matches against the country codes and count how many there are for each.
e.g (?)
gov.[country code]
Ideally, I would like the output to be grouped by country name and counted, something like, using the above URLs as an example, it might result in:
country | total
United States | 2
Russia | 1
Like I said, not sure if this can be done in MySQL with regex, substrings etc. Would love to know if it can be.
You could use a query like this:
SELECT
c.country,
COUNT(*)
FROM
countries c INNER JOIN URLS u
ON SUBSTRING_INDEX(SUBSTRING_INDEX(url, 'http://', -1), '/', 1)
LIKE CONCAT('%', c.code)
GROUP BY
c.country
Please see fiddle here.
Using SUBSTRING_INDEX(url, 'http://', -1) you can get the whole string after the http://
http://example.gov.ru/index.php ---> example.gov.ru/index.php
then using SUBSTRING_INDEX(..., '/', 1) on this string you can get the part of the string before the first / or the whole string if there's no /
example.gov.ru/index.php ---> example.gov.ru
you can then check if example.gov.ru LIKE '%.ru'
select country, count(*) total
from country_codes c
join urls on urls.url RLIKE CONCAT("^http://[^/]+\\.gov\\.", c.code, "($|/)")
group by county

mysql query two tables

I need to query two tables like this...
table one
customers
id companyname phone
1 | microsoft | 888-888-8888
2 | yahoo | 588-555-8874
3 | google | 225-558-4421
etc...
table two
contacts
id companyid name phone
1 | 1 | sam | 558-998-5541
2 | 1 | john | 558-998-1154
3 | 3 | larry | 111-145-7885
4 | 3 | dave | 558-998-5254
5 | 2 | sam | 558-997-5421
I need to query both tables.
So if I search for sam
it should return a list of companies with the contacts
microsoft 888-888-8888
sam 558-998-5541
john 558-998-1154
yahoo 588-555-8874
sam 558-997-5421
so it returns all company with sam and all contacts with it....
same is if I would search 'microsoft' it should return without yahoo
microsoft 888-888-8888
sam 558-998-5541
john 558-998-1154
and if I search "558-998-1154" it should return like this...
microsoft 888-888-8888
sam 558-998-5541
john 558-998-1154
I hope this is clear....
Here is my current query:
SELECT * FROM
customers, customer_contacts
WHERE (customers.code LIKE '%#URL.qm1#%'
or customers.COMPANY LIKE '%#URL.qm1#%'
or customers.phone LIKE '%#URL.qm1#%'
or customers.contact LIKE '%#URL.qm1#%'
or customers.name LIKE '%#URL.qm1#%'
or customers.address1 LIKE '%#URL.qm1#%')
AND (customers.id = customer_contacts.cid
and customer_contacts.deleted = 0)
this returns only those who have a contact...
I would need
it to return the ones without contacts as well.
This is a sticky problem, one that I almost want to say "don't try to do this is one query".
I approach SQL queries like this from a programming perspective, as I feel the results tend to be less "magical". (A property I see in too many queries — it seems SQL queries these days are written using monkeys at keyboards…)
Figure out which company IDs we want to list. This is the union of these two things:
Any "people" results matched on name or number
Any "company" results matched on name or number
List out the number for that company, and the people as well.
Let's do #2 first:
SELECT
companyname AS name,
phone
FROM
customers
WHERE id IN (company_ids we want)
UNION
SELECT
name, phone
FROM
contacts
WHERE companyid IN (company_ids we want)
Since "company_ids we want" is going to be a query, rearrange this to boil it down to just 1 occurrence:
SELECT
name, phone
FROM
(
SELECT
id AS companyid,
companyname AS name,
phone
FROM
customers
UNION
SELECT companyid, name, phone FROM contacts
) AS entities
WHERE
companyid IN (company_ids we want)
Now, to fill in the fun part, we need to answer #1:
Part #1.1 is:
SELECT companyid FROM contacts WHERE name = $search OR number = $search;
Part #1.2 is:
SELECT id AS companyid FROM customers WHERE companyname = $search OR number = $search;
(Note that $search is our input — parameterized queries differ greatly from one SQL vendor to the next, so replace that syntax as needed.)
Put the UNION of those two in the IN, and we're done:
SELECT
name, phone
FROM
(
SELECT
id AS companyid,
companyname AS name,
phone
FROM
customers
UNION
SELECT companyid, name, phone FROM contacts
) AS entities
WHERE
companyid IN (
SELECT companyid FROM contacts WHERE name = $search OR phone = $search
UNION
SELECT id AS companyid FROM customers WHERE companyname = $search OR phone = $search
)
;
And pray the database can figure out a query plan that performs this in a reasonable amount of time. Sure you don't want to roundtrip to the DB a few times?
Note the methodology: We determined what we wanted ("the names/phones for customers/contacts matching certain companyids") and then figured out the missing piece ("which company ids?"). This comes from the fact that once you match a particular person in a company (say, sam), you want everyone from that company, plus the company, or everything with that company ID. Knowing that, we get our outer query (#2), and then we just need to figure out how to determine which companies we're interested in.
Note that these won't (and SQL queries, without an ORDER BY don't) give the queries back in your rather fancy order. You can add a helper column to the inner query, however, and accomplish this:
SELECT
name, phone
FROM
(
SELECT
0 AS is_person,
id AS companyid,
companyname AS name,
phone
FROM
customers
UNION
SELECT 1 AS is_person, companyid, name, phone FROM contacts
) AS entities
WHERE
companyid IN (
SELECT companyid FROM contacts WHERE name = $search OR phone = $search
UNION
SELECT id AS companyid FROM customers WHERE companyname = $search OR phone = $search
)
ORDER BY
companyid, is_person, name
;
You can also use the is_person column (if you add it to the SELECT) if you need to segment the results in whatever gets this query's results.
(And if you end up using queries of this length, please, for the love of God, -- comment them!)