I have a table with 3 columns: Animal, key, owner. Example
Cat 1 Bob
Bird 2 Bob
dog 3 Bob
dog 4 Andy
Lizard 5 Andy
Bird 6 Andy
Cat 7 Andy
and one related table per animal (columns key, weight). For example, table CAT_WEIGHT:
1 12
7 17
I want to find the Min, Max, Average, Total, and Count for each animal type, but only for a particular owner.
Is this possible to calculate these using a single MYSQL query? I know I can do it in multiple queries but am looking for the best way.
Thanks
Yes it is possible to do this using just one query.
All other things being equal you want to use as few queries as possible. Roundtrips to the database are generally some of the more expensive things you'll encounter in programs.
select
animal,
min(weight) min_weight,
max(weight) max_weight,
avg(weight) avg_weight,
sum(weight) tot_weight,
count(weight) cnt_weight
from
your_table
group by
animal
order by animal;
How about:
select min(Weight), max(Weight), sum(Weight), count(*) from animals_table group by animal
Related
I know this is probably so odd to ask. But lets say I have 3 tables:
Table 1
ID
Name
1
Adam
2
David
3
Conor
Table 2
ID
Name
1
Adam
2
Derek
3
Niall
Table 3
ID
Name
1
Adam
2
David
3
John
Is there any way I can write a query to get the unique names across all 3 tables. So it would return "Adam, David, Conor, Derek, Niall, John"
Order doesn't matter
If it helps, all name values are related to a names table
yes , one way is to union them
select name from table1
union
select name from table2
union
select name from table3
union automatically removes duplicate cases
Forgive me, I'm still learning but am in need of some assistance. Some of what I’ve done is an amalgam of previous questions but I can’t find quite what I’m looking for.
I have a table with 30 columns of data, let’s call it table1. Every two columns are actually a set of the same type of data that have meaning together and singly. For example col1 with col2, is say a set of names.
Like this:
1 Jim Jeff
2 Mike Ben
3 Mike Mike
4 Peter Jeff
5 Jeff Jim
6 etc etc
The remaining 28 columns aren't important at this point. I want to return a single list of the unique names in col1 AND col2 along with their counts in total from both columns. Here’s what I have and it seems to work to a point but there is a problem with the return.
SELECT col1, COUNT(*)
FROM table1
GROUP BY col1
UNION
SELECT col2, COUNT(*)
FROM table2
GROUP BY col2
The problem is, when col1 has a name in it that is also in col2 it will return two counts. For example, if I had 6 different names, a total of 100 times, 50 in each column I might see something like this returned with the above query.
Jim 4
Jim 13
Jeff 8
Jeff 19
Mike 11
Mike 34
Ben 4
Brian 2
Peter 5
Obviously, Jim, Jeff and Mike appear in both columns and Ben, Brian and Peter appear in only one (It seems to me that it doesn’t matter which one).
What I need returned is:
Jim 17
Jeff 27
Mike 45
Ben 4
Brian 2
Peter 5
I tried putting a subquery in GROUP BY to force what is returned by a union without the count (forgive me, I don’t know much SQL, I'm just making assumptions by what little I understand of the language), meaning:
GROUP BY (SELECT col1 FROM table1 UNION SELECT col2 FROM table2)
but I guess I’m making silly assumptions. Any suggestions?
You can use a CTE to get the list of all names, then do a count based on that.
;WITH Names AS
(
SELECT col1 AS [Name]
FROM table1
UNION ALL
SELECT col2 AS [Name]
FROM table2
)
SELECT [Name], COUNT(*)
FROM Names
GROUP BY [Name]
I have a this Table in MS Access:
Table1
ID EMP ROLE ASSESS
1 JOE Weld 4
2 TOM Weld 4
3 JIM Ship 4
4 PAT Ship 3
5 JAY Weld 4
6 TIM Ship 4
"ROLE" is short text and "ASSESS" is a number field. "ASSESS" is assessing employees' roles on a scale of 1-4. I want to collect and total assessments that are "4" for each role.
Returning something like:
ROLE TOTAL
Weld 3
Ship 2
I however have around 100 different roles that I am needing to do this with. Is there a way with SQL or a combination of query and macro to make this work? I am at a loss.
Thank you.
You could use a where clause to filter just the the assesses that are 4 and a group by clause to aggregate them:
SELECT role, COUNT(*)
FROM table
WHERE assess = 4
GROUP BY role
I appreciate that this may appear to many as a dum question but I cannot find a clear explanation anywhere as to what the effect of "group by" has on a select max(...) from SQL statement.
I have the following data (there is another column image of type mediumblob which is not shown):
id title test_id
1 bomb 0
2 Soft watch 2
3 Dali 1
4 Narciss 1
5 The Woman In Green 0
6 A summer in Vetheuil 0
7 Artist's Garden 2
8 Beech Forest 2
9 Claude Monet 0
I know if I perform
select max(id) from images
where image is not null;
I get the max value of id i.e.:
max(id)
9
However can someone please explain what is happening when I perform
select max(id), title, test_id
from images
where image is not null
group by id;
I find that the max(id) serves no useful purpose (results shown below)?
max(id) title test_id
1 bomb 0
2 Soft watch 2
3 Dali 1
4 Narciss 1
5 The Woman In Green 0
6 A summer in Vetheuil 0
7 Artist's Garden 2
8 Beech Forest 2
9 Claude Monet 0
In the case of using MAX() the GROUP BY clause essentially tells the query engine how to group the items from which to determine a maximum. In your first example you were selecting only a single column, so there was no need for grouping. But in your second example you had multiple columns. So you need to tell the query engine how to determine which ones are going to be compared to find a maximum.
You told it to group by the id column. Which means that it's going to compare records which have the same id and give you the maximum one for each unique id. Since every record has a different id, you essentially didn't do anything with that clause.
It grouped all records with an id of 1 (which was a single record), and returned the record with the maximum id from that group (which was that record). It did the same for 2, 3, etc.
In the case of the three columns shown here, the only place where it would make sense to group your records would be on the test_id column. Something like this:
SELECT MAX(id), title, test_id
FROM images
WHERE image IS NOT null
GROUP BY test_id
This would group them by the test_id, so the results will include records 6 (the maximum id for test_id 0), 4 (the maximum id for test_id 1), and 8 (the maximum id for test_id 2). By splitting the records into those three groups based on the three unique values in the test_id column, it can effectively find a "maximum" id within each group.
Yes, in your example it serves no useful purpose.
You're grouping by ID then finding the maximum ID. But that doesn't make sense since there's only one of each ID. Normally MAX() is used on quantities, like prices or item counts or such like.
Group by is not used for this kind of queries
Its is used for queries like this
OId OrderDate OrderPrice Customer
1 2008/11/12 1000 Hansen
2 2008/10/23 1600 Nilsen
3 2008/09/02 700 Hansen
4 2008/09/03 300 Hansen
5 2008/08/30 2000 Jensen
6 2008/10/04 100 Nilsen
Now if you want to get sum of material bought by each customer of these you will use group by
SELECT Customer,SUM(OrderPrice) FROM Orders
GROUP BY Customer
customer SUM(OrderPrice)
Hansen 2000
Nilsen 1700
Jensen 2000
In above case id is unique so group by id will not make any sense
Sorry if the title is not clear. I am a bit confused about how to plan my database schema as given my database design skill level the requirement falls under kind of advanced :) I could really use some help here. Anyway, here it goes ...
I need to track match details for teams. For the sake of simplicity, lets say I need to track the match date, result and the teams that played the match. Now, how do I design my tables so I can make sure all relevant data is returned without having to keep multiple records of the same match. I am not sure if I am explaining clearly, so here's an example below.
match_id team1 team2 result
________ ________ ________ ________
1 Arsenal Chelsea 5-3
2 Manchester Utd Arsenal 1-0
3 Liverpool Newcastle 2-0
4 Arsenal Everton 1-0
From this data, if I search for match_ids for matches played by Arsenal, I should get the below results,
1,2,4.
Now, in the basic designs which I know of, I would normally search for matched in team name for the team name supplied and return the result. But here the team name can be in two different columns and both can be relevant. So, is it something I need to decide on the design level or something that can be done with some sort of query.
(Note: Storing teams as home/away is not an option for my requirement).
You can just query both columns, it's not a problem:
select match_id
from matches
where team1 = 'Arsenal' or team2 = 'Arsenal';
(You could also normalize this schema by placing teams in their separate table and leaving only their ids in the matches table, but that doesn't change much, you still have to query both columns. Read about database normalization, any SQL book covers this).
If there are always two teams per match, then I think you did a good job here, and when querying for a particular team, you'll want to search for one column OR the other (SELECT match_id FROM matches WHERE team1 = "?" OR team2 = "?").
One note though: I would definitely split up the score into two columns:
match_id team1 team2 score1 score2
________ ______________ _________ ______ ______
1 Arsenal Chelsea 5 3
2 Manchester Utd Arsenal 1 0
3 Liverpool Newcastle 2 0
4 Arsenal Everton 1 0
This way you'll be able to query on scores later on, if you need it. (e.g. Big wins = SELECT match_id FROM matches WHERE ABS(score1 - score2) > 3;)
The other option you have should be more scalable if there exists a possibility of having more than two teams per match. If this is the case, then you'd likely want to remove the uniqueness constraint on match_id and cut out the team/score columns from 2 to 1:
match_id team score
________ ________ ____
1 Arsenal 5
1 Chelsea 3
2 Manchester Utd 1
2 Arsenal 0
3 Liverpool 2
3 Newcastle 0
4 Arsenal 1
4 Everton 1
And of course, you're definitely going to want to take Sergio's advice in putting all this stuff into separate tables. "Teams" are likely going to have different attributes (hometown, coach name, etc.), and you're not going to want to duplicate that data.
This will give you the results you want but there may be a better design too.
Select *
from table
where (team1 = 'ARSENAL' or Team2 = 'ARSENAL')
You may want to Separate out scores such as Team1Score Team2Score otherwise you can't easily do math with them.
for star I would not store the time name, I think its better if you store the times in other table and linq then thru an id.
And then you could create a table with columns id, match id and team id, and just search for the team id in that table!
you can used this query and its no problem for your program:
select YOUR_ID_FIELDS
from YOUR_TABLE_NAME
where YOUR_FIELD_NAME(team1) = 'Arsenal' or YOUR_FIELD_NAME(team2) = 'Arsenal';
and for exmale (Chelsea)
select YOUR_ID_FIELDS
from YOUR_TABLE_NAME
where YOUR_FIELD_NAME(team1) = 'Chelsea' or YOUR_FIELD_NAME(team2) = 'Chelsea';