Query using two tables with DISTINCT - mysql

I have two tables - clients and - group
I need to get county and zip from clients and group-assigned from group
When I search, I cannot get distinct results, that is, instead of the output showing 100 clients with zipcode 12345 in jones county in main st group.
I need to have each zip and county listed once by group. I have googled and attempted many ways but it is just beyond me.
Can anyone assist in steering me to the correct way

Adding GROUP BY group, city, zip to the end of your query should get you what you need. It will only return unique combinations of the three.

Presumably you have something like:
select g.*, c.county, c.zip
from clients c join groups g on <some join condition>
You want one result per group. So, add a group by clause such as:
group by g.id -- assuming id uniquely identifies each group
This will give an arbitrary value for the other fields, which may be sufficient for what you are doing. (This uses a MySQL features called Hidden Columns.)

Related

Have to enter mySQL criteria twice?

Say I have two tables:
Table: customers
Fields: customer_id, first_name, last_name
Table: customer_cars
Fields: car_id, customer_id, car_brand, car_active
Say I am trying to write a query that shows all customers with a first name of "Karl," and the brands of the ** active ** cars they have. Not all customers will have an active car. Some cars are active, some are inactive.
Please keep in mind that this is a representative example that I just made up, for sake of clarity and simplicity. Please don't reply with questions about why we would do it this way, that I could use table aliases, how it's possible to have an inactive car, or that my field names could be better written. It's a fake example that is intended be very simple in order to illustrate the point. It has a structure and issue that I encounter all the time.
It seems like this would be best done with a LEFT JOIN and subquery.
SELECT
customer_id,
first_name,
last_name,
car_brand
FROM
customers
LEFT JOIN
(SELECT
customer_id,
car_brand
FROM
customer_cars
INNER JOIN customers ON customer_cars.customer_id = customers.customer_id
WHERE
first_name = 'Karl' AND
customer_cars.car_active = '1') car_query ON customers.customer_id = car_query.customer_id
WHERE
first_name = 'Karl'
The results might look like this:
first_name last_name car_brand
Karl Johnson Dodge
Karl Johnson Jeep
Karl Smith NULL
Karl Davis Chrysler
Notice the duplication of 'Karl' in both WHERE clauses, and the INNER JOIN in the subquery that is the same table in the outer query. My understanding of mySQL is that this duplication is necessary because it processes the subquery first before processing the outer query. Therefore, the subquery must be properly limited so it doesn't scan all records, then it tries to match on the resulting records.
I am aware that removing the car_active = '1' condition would change things, but this is a requirement.
I am wondering if a query like this can be done in a different way that only causes the criteria and joins to be entered once. Is there a recommended way to prioritize the outer query first, then match to the inner one?
I am aware that two different queries could be written (find all records with Karl, then do another that finds matching cars). However, this would cause multiple connections to the database (one for every record returned) and would be very taxing and inefficient.
I am also aware of correlating subqueries, but from my understanding and experience, this is for returning one field per customer (e.g., an aggregate field such as how much money Karl spent) within the fieldset. I am looking for a similar approach as this, but where one customer could be matched to multiple other records like in the sample output above.
In your response, if you have a recommended query structure that solves this problem, it would be really helpful if you could write a clear example instead of just describing it. I really appreciate your time!
First, is a simple and straight query not enough?
Say I am trying to write a query that shows all customers with a first
name of "Karl," and the brands of the ** active ** cars they have. Not
all customers will have an active car. Some cars are active, some are
inactive.
Following this requirement, I can just do something like:
SELECT C.first_name
, C.last_name
, CC.car_brand
FROM customers C
LEFT JOIN cutomer_cars CC ON CC.customer_id = C.customer_id
AND car_active = 1
WHERE C.first_name = 'Karl'
Take a look at the SQL Fiddle sample.

MySql total is bigger than individual elements

I have a huge MySql table that is in use in production. I have tables which are named by geographical areas with foreign keys for smaller divisions. It is structured like db_country-> tbl_city1, tbl_city2, tbl_city3 and each tbl_city has rows for households inside with other details like street, address and number of people for each household.
PROBLEM: If I pull the data for each family grouped by STREETS I get the correct number of people but when I call the number of people in the entire city, I get a slightly inflated number. I know there must be something I've messed up, what is the possible fail area in this scenario?
The first query that yields inflated output is:
SELECT sum(people) AS people FROM city WHERE division=2136 AND status=1;
and the second query that yields correct output is:
SELECT street.name, SUM(people) AS people FROM city INNER JOIN streets
ON city.street=streets.id WHERE division=2136 AND status=1
GROUP BY street.name;
The picture is the real output, above table shows combined total(inflated) while the lower one shows individual streets/villages with the correct number MYSQL OUTPUT IMAGE
There are records in city table which have no related street record matching the join city.street=streets.id.
Try this sql to find out the missed records.
Select city.* from city left join street on city.street=streets.id
WHERE division=2136 AND status=1 where street.id is null.

count number of repeating entries

I am fairly new to Databases and I am just beginning to understand the DML/queries, I have two tables, one named customer this contain customer data and one named requested_games, this contains games requested by the customers, I would like to write a query that will return the customers that have requested more than two games, so far when I run the query, I don't get the desired result, not sure if I'm doing it right.
Can anyone assist with this thanks,
Below is a snippet of the query
select customers.customer_name, wants_list.requested_game, wants_list.wantslists_id,count(wants_list.customers_ID)
from customers, wants_list
where customers.customers_ID = wants_list.customers_id
and wants_list.wantslists_id = wants_list.wantslists_id
and wants_list.requested_game > '2';
just include a HAVING clause
GROUP BY customers_ID
HAVING COUNT(*) > 2
depending on how you have your data setup you may need to do
HAVING COUNT(wants_list.requested_game) > 2
This is how I like to describe how a query works maybe itll help you visualize how the query executes :)
SELECT is making an order at a restaurant....
FROM is the menu you want to order from....
JOIN is what sections of the menu you want to include
WHERE is any customization you want to make to your order (aka no mushrooms)....
GROUP BY (and anything after) is after the order has been completed and is at your table...
GROUP BY tells your server to bring your types of food together in groups
ORDER BY is saying what dishes you want first (aka i want my entree then dessert then appetizer ).
HAVING can be used to pick out any mushrooms that were accidentally left on the plate....
etc..
I would like to write a query that will return the customers that
have requested more than two games
For this to happen you need to do the following
First you need to use GROUP BY to group the games based on customers (customers_id)
Then you need to use HAVING clause to get customers who requested more than two games
Then make this a SUBQUERY if you need more information on the customer like name
Finally you use a JOIN between customers and the sub query (temp) to display more information on the customer
Like the following query
SELECT customers.customer_id, customers.customer_name, game_count
FROM (SELECT customer_id, count(wantslists_id) AS game_count
FROM wants_list
GROUP BY customer_id
HAVING count(requested_game) > '2') temp
JOIN customers ON customers.customer_id = temp.customer_id

SQL Count and Group By issue

I have a table Mbr that contains 3 fields, GroupType, LeaderID, and MemberID. Basically, all the members in an organization are divided up into these groups, identified by their leader's unique ID (LeaderID). Each member record also has their own MemberID, and the leaders themselves have a unique MemberID as well. The GroupType just designates whether the group a member is in which is considered a Large, Small, or Individual group.
I need to find out how many groups of each GroupType contain a certain number of members.
For example:
How many Large groups contain 6 members, 7 members, 8 members, 9 and so on.
How many Small Groups contain 2 members, 3 members, 4 members and 5 members
How many Individual groups there are.
Is it possible make a query to get a Count of the unique MemberID's for each group, and then get a COUNT of how many LeaderID's have a certain number of members associated to them?
Note: Since you are not specifying which DBMS you are using, I tried to do a basic query. In SQLServer or Oracle this can be much more elegant.
I'm assuming that a given Member can be Leader leader of only one Group if that is correct,
Question #1:
SELECT GroupType, NumberOfMembers, COUNT(LeaderID) AS NumberOfGroups
FROM (
SELECT GroupType, LeaderID, COUNT(*) AS NumberOfMembers
FROM MyTable
GROUP BY GroupType, LeaderID
) AS InnerGrouping
GROUP BY GroupType, NumberOfMembers
ORDER BY GroupType, NumberOfMembers
Question #2:
SELECT UniqueMemberIDPerGroup, COUNT(LeaderID) AS NumberOfLeaderID
FROM (
SELECT LeaderID, COUNT(DISTINCT MemberID) AS UniqueMemberIDPerGroup
FROM MyTable
GROUP BY LeaderID
) AS InnerGrouping
GROUP BY UniqueMemberIDPerGroup
I'm sure you can write some complex query with several subqueries to create a query to give you what you want, but I personally like more straightforward methods. In this case, it would be using some temp tables to store intermediate values. I would first group by several columns (that you are going to use as criterias) with count being the value for the query. I would then store these into a temp table and finally create a query to utilize the temp table to give you the results that you are looking for.

Query MySQL for rows that share a value, and returning them as columns?

This is for a homework assignment. I haven't copy-pasted the question below, I made an simpler version of it that focuses on the specific area where I'm stuck.
Let's say I have a table of two values: a person's name, and the place he had lunch yesterday. Assume everyone has lunch in pairs. How can I query the database to return all the pairs of people that had lunch together yesterday? Each pair must be only listed once.
I'm actually not even sure what the professor means by return them as pairs. I've sent him an email, but no reply yet. It seems like he wants me to write a query that returns a table with column 1 as person 1 and column 2 as person 2.
Any suggestions on how to go about this? Does it seem right to assume he wants them as separate columns?
So far, I basically have:
SELECT name, restaurant FROM lunches GROUP BY restaurant, name
which essentially just reorganizes the table so that the people who had lunch together are one after the other.
We have to assume there can be only one pair eating lunch in a given restaurant.
You can get a list of pairs either using self-join:
SELECT l1.name, l2.name FROM lunches l1
JOIN lunches l2
ON l1.restaurant = l2.restaurant AND l1.name < l2.name
or using GROUP BY:
SELECT GROUP_CONCAT(name) FROM lunches
GROUP BY restaurant
The first query will return pairs in two different columns, while the second in one column, using comma as separator (default for GROUP_CONCAT, you can change it to whatever you wish).
Also note that for the first query names in pairs will come in alphabetical order as we use < instead of <> to avoid listing each pair twice.