So I have two tables that I need information from. I have a
ballot_table(vote CHAR(30), username CHAR(30)) that has the name of the candidate each username voted for. I also have another table with a list of the candidates. I need someway to return the list of candidates with the corresponding amount of times there name appears in ballot_table in the same query. Thanks!
This is a horrible design but here is how you do it:
select count(*) as votes, vote as [candidate]
from ballot_table
where ucase(vote) in (select ucase(item) from table_with_list_of_candidates)
group by ucase(vote)
a better design would have the list of candidates table include a key and then just have the key in the ballot_table with a varchar for a write in (if needed).
You can do this with an Outer Join and a Group By. I'm assuming the field name in the candidate table is Name.
Select c.Name, Count(Distinct b.UserName) Votes
From ballot_table b
Right Join candidate c On c.Name = b.Vote
Group By c.Name
This would only return the total votes for the candidates you have in your Candidate table. Any other "write-in" vote wouldn't be included.
Related
Sorry If that's terrible phrasing. Basically I need to make a query that tells me the club name and description from 'clubs', with the total number of students in that club. Students can only be in 1 club so clubID is a Foreign key in 'students'.
I tried to use the below, but quickly learned I'm nowhere near the answer. Is this possible?
SELECT clubs.clubName, clubs.clubDescription, COUNT(students.studentID)
FROM club JOIN students ON students.clubID = clubs.clubID
You need to add group by clause with clubs.clubName, clubs.clubDescription columns as count() is an aggregate function
SELECT clubs.clubName, clubs.clubDescription, COUNT(students.studentID)
FROM club JOIN students ON students.clubID = clubs.clubID
group by clubs.clubName, clubs.clubDescription
If you want to include clubs that have no students, you want an outer join or correlated subquery:
select c.*,
(select count(*) from students s where s.clubID = c.clubId) as num_students
from clubs c;
I have the following Database Structure
Table Employee:
Name ENr
Name 1 1
Name 2 2
Name 3 3
...
Table Travel:
Employee Costs
Name 1 8000
Name 1 56000
Name 2 800
and so on.
Now I want to Select The Name of the employees, the Count of the Travels and the Average Costs, as well as the ENr
Thats my SQL Select so far:
SELECT employee, COUNT(travel.employee), AVG(costs) FROM travel GROUP BY employee
However, as soon as I try to connect with the employee Table to add the ENr, my count is simply wrong.
I tried to connect with simple:
SELECT ENr, Employee.. FROM travel, employee
And also with an INNER JOIN.
Hope somebody could help me out :)
Never use commas in the FROM clause. Always use proper, explicit JOIN syntax.
You need JOIN conditions:
SELECT e.name, e.eNR, COUNT(*), AVG(t.costs)
FROM employee e JOIN
travel t
ON e.name = t.name
GROUP BY e.name, e.eNR;
Additional comments:
When you have more than one table in a query, use table aliases and qualified column names.
Include all non-aggregated columns in the GROUP BY.
name is a lousy foreign key. Usually, you want foreign keys to be unique (names may not be unique). And numbers are more efficient for indexing purposes.
The Select below summarizes the customer totals, but I need the customers first buy code to show where they first came from.
Select is:
SELECT h.buycode, Min(h.sdate) AS firstBuy, h.i_id,a.eid,count(*) AS orders,Sum(h.i_total) AS revenue,Max(h.sdate) AS LastBuy, a.eid, a.c_id
FROM mk_adr a
INNER JOIN oe_hdr h
ON h.c_id = a.c_id
WHERE h.sdate is not null
GROUP BY a.eid
eid is the enterprise ID that ties all of the c_id's(customer_id) together. A customer can have multiple c_id's, but only 1 eid. Eid is not part of the table oe_hdr.
I've tried using a sub-select with a left join and min(sdate) on oe_hdr, buycode, but it mostly returns null values for buycode.
This may not be the best way, but you can create a table that only holds the first purchase for the user. it places a foreign key to the user, and to the first item that they bought. Then you can just select from that table.
LOGIC:
IF -the user has no buys in the table- THEN
-Place the information in the first buy table-
I have two table in MySQL
Table 1: List of ID's
--Just a single column list of ID's
Table 2: Groups
--Group Titles
--Members **
Now the member field is basically a comments field where all the ID's that are part of that group are listed. So for instance one whole field of members looks like this:
"ID003|ID004|ID005|ID006|ID007|ID008|... Etc."
There they can be up to 500+ listed in the field.
What I would like to do is to run a query and find out which ID's appear in only three or less groups.
I've been taking cracks at it, but honestly I'm totally lost. Any ideas?
Edit; I misunderstood the question the first time, so I'm changing my answer.
SELECT l.id
FROM List_of_ids AS l
JOIN Groups AS g ON CONCAT('|', g.members, '|') LIKE CONCAT('%|', l.id, '|%')
GROUP BY l.id
HAVING COUNT(*) <= 3
This is bound to perform very poorly, because it forces a table-scan of both tables. If you have 500 id's and 500 groups, it must run 250000 comparisons.
You should really consider if storing a symbol-separated list is the right way to do this. See my answer to Is storing a delimited list in a database column really that bad?
The proper way to design such a relationship is to create a third table that maps id's to groups:
CREATE TABLE GroupsIds (
memberid INT,
groupid INT,
PRIMARY KEY (memberid, groupid)
);
With this table, it would be much more efficient by using an index for the join:
SELECT l.id
FROM List_of_ids AS l
JOIN GroupsIds AS gi ON gi.memberid = l.id
GROUP BY l.id
HAVING COUNT(*) <= 3
select * from
(
select ID,
(
select count(*)
From Groups
where LOCATE(concat('ID', a.id, '|'), concat(Members, '|'))>0
) as groupcount
from ListIDTable as a
) as q
where groupcount <= 3
I have two tables: groups and group_members.
The groups table contains all the information for each group, such as its ID, title, description, etc.
In the group_members table, it lists all the members who are apart of each group like this:
group_id | user_id
1 | 100
2 | 23
2 | 100
9 | 601
Basically, I want to list THREE groups on a page, and I only want to list groups which have MORE than four members. Inside the <?php while ?> loop, I then want to four members who are apart of that group. I'm having no trouble listing the groups, and listing the members in another internal loop, I just cannot refine the groups so that ONLY those with more than 4 members show.
Does anybody know how to do this? I'm sure it's with MySQL joins.
MySQL use HAVING statement for this tasks.
Your query would look like this:
SELECT g.group_id, COUNT(m.member_id) AS members
FROM groups AS g
LEFT JOIN group_members AS m USING(group_id)
GROUP BY g.group_id
HAVING members > 4
example when references have different names
SELECT g.id, COUNT(m.member_id) AS members
FROM groups AS g
LEFT JOIN group_members AS m ON g.id = m.group_id
GROUP BY g.id
HAVING members > 4
Also, make sure that you set indexes inside your database schema for keys you are using in JOINS as it can affect your site performance.
SELECT DISTINCT groups.id,
(SELECT COUNT(*) FROM group_members
WHERE member_id = groups.id) AS memberCount
FROM groups
Your groups_main table has a key column named id. I believe you can only use the USING syntax for the join if the groups_fans table has a key column with the same name, which it probably does not. So instead, try this:
LEFT JOIN groups_fans AS m ON m.group_id = g.id
Or replace group_id with whatever the appropriate column name is in the groups_fans table.
Maybe I am off the mark here and not understanding the OP but why are you joining tables?
If you have a table with members and this table has a column named "group_id", you can just run a query on the members table to get a count of the members grouped by the group_id.
SELECT group_id, COUNT(*) as membercount
FROM members
GROUP BY group_id
HAVING membercount > 4
This should have the least overhead simply because you are avoiding a join but should still give you what you wanted.
If you want the group details and description etc, then add a join from the members table back to the groups table to retrieve the name would give you the quickest result.