Selecting Distinct Entries across columns? - mysql

I have a database that tracks the prizes that people win across the booths of a fair. Most of the booths have overlapping and similar prizes, so a participant can win a Pillow (for example) from 2 booths.
Now, we want to be able to track how many people won a given prize, since we want to tally and account how many people won a certain prize already.
Here is how the table looks like:
It's easy to get the count of a certain prize in a given column. However, I'm having problems trying to consolidate the data across multiple columns.

If you can't normalize your table, a bunch of union alls could do the trick:
SELECT prize, COUNT(*)
FROM (SELECT station_1_prize AS prize FROM mytable
UNION ALL
SELECT station_2_prize AS prize FROM mytable
UNION ALL
-- Etc...
) t
GROUP BY prize

Related

entries in multiple dates in access

I have a access table that has quarterly pricing data starting from 20100131 and goes on as 20100430, 20100731.... 20170131, 20170430. For each pricing date, there are many loans. Some loans stay in the portfolio, some loans are removed and some added for each pricing period. I would like to find the list of loans that exist in all periods and see their price for each period. So i have the "Loan_Number" field and "Price_Date" field. I would like to find the Loan Numbers that exist in all price date points. I appreciate the help.
Thanks!
Would have been nice to see some effort from you but I was intrigued with the challenge so here is what I accomplished.
1 - Need a dataset of all possible combinations of loan numbers and date values. So if you have a LoanNumbers table and a Periods table, create a Cartesian query called AllPairs:
SELECT LoanNumbers.Loan_Number, Periods.Price_Date FROM LoanNumbers, Periods;
If you don't have those tables, generate datasets with queries, assuming the data table has at least one record for every loan number and at least one record for every period:
SELECT DISTINCT Table1.Price_Date FROM Table1;
SELECT DISTINCT Table1.Loan_Number FROM Table1;
2 - Join AllPairs to data table for a 'find unmatched' query called LoanNoPeriod:
SELECT AllPairs.Loan_Number, AllPairs.Price_Date, Table1.Loan_Number, Table1.Price_Date
FROM AllPairs LEFT JOIN Table1 ON (AllPairs.Price_Date = Table1.Price_Date) AND (AllPairs.Loan_Number = Table1.Loan_Number)
WHERE (((Table1.Price_Date) Is Null));
3 - Final query:
SELECT * FROM Table1 WHERE Loan_Number NOT IN (SELECT AllPairs.Loan_Number FROM LoanNoPeriod);
Be aware these type of queries can perform very slowly and with very large datasets might not be practical.

Joining mysql tables on multiple fields

I have a sports site where I have a teams table and a games table. The teams table has the team id, name, and logo(url). The games table has the game id, date, time, hometeamid, and awayteamid.
I'm trying to come up with a mysql query that will return the list of games that includes the associated team names and logos that go with their ids.
Right now, I'm pulling the list of games with their hometeamid and awayteamid, then I'm going back to do a query on the teams table with the hometeamid to get their name and logo, then repeating with the awayteamid to get their name and logo.
That seems like a lot of hitting the db, especially if I can somehow join them in the one first query.
Many thanks for any help you can give.
Let's say you have tables:
TEAM with fields T_ID, NAME, URL
GAME with fields G_ID, T_ID1, T_ID2, others...
A joined select in your case would be:
Select a.G_ID,b.NAME,c.NAME from GAME a, TEAM b, TEAM c where a.T_ID1=c.T_ID and a.T_ID2=b.T_ID
Let us know if you need any more help

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.

MySQL Union (or similar) query

I have some booking data from a pair of views in MySQL. They match columns perfectly, and the main difference is a booking code that is placed in one of these rows.
The context is as follows: this is for calculating numbers for a sports camp. People are booked in, but can do extra activities.
View 1: All specialist bookings (say: a football class).
View 2: A general group.
Due to the old software, the booking process results in many people booking for the general group and then are upgraded to the old class. This is further complicated by some things elsewhere in the business.
To be clear - View 1 actually contains some (but are not exclusively all) people from within View 2. There's an intersection of the two groups. Obviously people can't be in two groups at once (there's only one of them!).
Finding all people who are in View 2 is of course easy... as is View 1. BUT, I need to produce a report which is basically:
"View 1" overwriting "View 2"... or put another way:
"View 1" [sort of] UNION "View 2"
However: I'm not sure the best way of doing this as there are added complications:
Each row is as approximately (with other stuff omitted) as follows:
User ID Timeslot Activity
1 A Football
1 A General
2 A General
3 A Football
As you can see, these rows all concern timeslot A:
- User 2 does general activities.
- User 3 does football.
- User 1 does football AND general.
AS these items are non unique, the above is a UNION (distinct), as there are no truly distinct rows.
The output I need is as follows:
User ID Timeslot Activity
1 A Football
2 A General
3 A Football
Here, Football has taken "precedence" over "general", and thus I get the picture of where people are at any time.
This UNION has a distinct clause on a number of fields, but ignores others.
So: does anyone know how to do what amounts to:
"add two tables together and overwrite one of them if it's the same timeslot"
Or something like a:
"selective distinct on UNION DISTINCT".
Cheers
Rick
Try this:
SELECT *
FROM
(SELECT *,
IF(Activity='General',1,0) AS order_column
FROM `Table1`
ORDER BY order_column) AS tmp
GROUP BY UserId
This will add an order_column to your original table that as value 1 if the Activity value is general; Doing this we can select this temporary table ordering by this column (ascending order) and all record with general activity comes after all others. After that we can simply select the result of this temporary table grouping by user id. The group by clouse without any aggregate function takes the first record that match.
EDIT:
If you don't to use group by without aggregate function this is an 'ugly' alternative:
SELECT UserId,
Timeslot,
SUBSTRING(MAX(CASE Activity WHEN "General" THEN "00General" WHEN "Football" THEN "01Football" ELSE Activity END) , 3)
FROM `Table1`
GROUP BY UserId,
Timeslot LIMIT 0 ,
30
Here we need to define each possible value for Activity.

What's the best way to combine 2 tables in MYSQL and remove duplicates?

I have 2 tables:
matches TABLE
FIELDS: record, date, competition
outrights TABLE
FIELDS: record, competition
What I would like, is to select rows grouped by the different types of competition. Below are the statements that work fine when I treat each table seperately.
Firstly, from 'matches' and only if the date hasn't already past:
SELECT competition, date FROM matches WHERE date >= '$currentTime' GROUP BY competition
Followed by rows from 'outrights':
SELECT competition FROM outrights GROUP BY competition
This is all pretty straight forward, except the same competition values will often (but not always) appear in both tables. I have looked at many different methods (including LEFT and RIGHT JOINS), but haven't found a simple solution. Basically I want the different competition types that appear in both tables, without duplication. Is this possible?
Is this what you are looking for. A little confused by the question but it appears that you want a DISTINCT listing of the competition column from both tables
SELECT DISTINCT competition
FROM
(
SELECT competition FROM matches
UNION
SELECT competition from outrights
) AS t
If you need the distinct competitions that appear only in both tables and not just one or both you could use
SELECT DISTINCT competition
FROM
(
SELECT competition FROM matches INNER JOIN
outrights ON matches.competition = outrights.competition
) AS t