I have two tables like so:
Table 1: tracks
id | artist | track
---------------------------------------
1 Tom Smith This Time is Right Time
2 Tom Smith Oh Yes
3 John Doe Every Time I See You
Table 2: festival_bands
id | fest_title | fest_artist
---------------------------------------
1 Hoe Down Fest 2019 John Doe
2 Copperland Fest Tom Smith
3 Copperland Fest Reggie Wisk
4 Copperland Fest Tom Smith
5 Copperland Fest John Doe
6 Bluegrass Memories John Doe
I need to show only ONE "track" from table 1 for each festival listing from Table 2 like so:
Results:
Copperland Festival:
-----------------------
Tom Smith This Time is Right Time
John Doe Every Time I See You
In layman's terms, the logic would be along the lines of:
Get only one track from TABLE 1 where artist equals (or matches) fest_artist from TABLE 2
I referenced a similar question which advised something in the direction of:
$sql="select * from tracks WHERE (artist) in (select fest_artist from festival_bands group by name)" but with no luck.
You can use a correlated subquery to get a random track for the artist:
select fb.*,
(select t.track
from tracks t
where t.artist = fb.fest_artist
order by t.counter desc
) as most_popular_track
from festival_bands fb;
Related
I am trying to decide which one is better: to design a table that wastes a lot of space and has a simple query OR to write a very tight table but then the process of finding what I am looking for would be very processing intense.
The actual problem is this:
Imagine you have a very simple table. 1st column for the ID number the 2nd is a list of names and the 3rd is a list of names too. The 2nd column is a list of people who owe to the people in the 3rd column.
The search should do the following:
I search for a name in the 3rd column and see who owes this person in the 2nd column. A name or multiple names come up, then I want to see who owes them, again a bunch of names come up, and so on to level 5.
Maybe this is a well known scheme for which there is a well known simple answer in table design or MySQL circles. Could anybody suggest a MySQL query or perhaps an appropriate table design where I can use a simple query?
Example
ID owes owned to
1 Peter John
2 John George
3 Abdul George
4 George Anna
So I could design a wasteful table like this
ID 1 2 3 4 5
1 Anna George Abdul
2 Anna George John Peter
3 George Abdul
4 George John Peter
5 John Peter
But this would be very wasteful and bad bad design but it would be very easy to access the data along with the hierarchy and the owing chain.
Something like this seems suitable:
people
+----+--------+
| id | name |
+----+--------+
| 1 | Marty |
| 2 | Steven |
| 3 | John |
+----+--------+
With the table building the relationships between people owed and owing:
loans
+-----------+-------------+
| lender_id | borrower_id |
+-----------+-------------+
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
+-----------+-------------+
You could get all the people owing a given lender with something as simple as:
SELECT people.id, people.name
FROM loans
INNER JOIN people ON people.id = loans.borrower_id
WHERE loans.lender_id = X
Where X is the id of the lender. Given the lender_id of 1 (Marty) for example would yield:
+----+--------+
| id | name |
+----+--------+
| 2 | Steven |
| 3 | John |
+----+--------+
You can repeat this process for each of the resulting people until there are no results (no one being owed).
I need to select the rows that do not have the first column matching. For example, from the data below;
Person | Room
---------------------------------------
ben | 1
jake | 3
jake | 1
steven | 2
james | 1
james | 2
james | 3
The query would only return these rows:
Person | Room
---------------------------------------
ben | 1
jake | 3
steven | 2
james | 1
It doesn't matter what value the room column returns.
And it needs to be able to work with increasing room numbers and different names.
I've had no look searching for a answer and can't figure out how to do it, however it might be my current mindset and it might be really easy to do.
SELECT Person, MIN(Room) AS Room
FROM YourTable
GROUP BY Person
And if you can guarantee that the ONLY_FULL_GROUP_BY setting will always be turned off, the following is also possible in MySql:
SELECT Person, Room
FROM YourTable
GROUP BY Person
But I'd use the MIN() function just to be safe...
I'm trying to figure out how to GROUP BY on multiple columns. I want to group items when the SSN or the address matches. For example, here are three records:
account_number | name | ssn | address
---------------+--------------+-------------+----------------------
23952352340 | SMITH INC | 123-45-6789 | P.O. BOX 123
3459450340 | JOHN SMITH | 123-45-6789 | 123 EVERGREEN TERRACE
45949459494 | JANE SMITH | 395-23-1924 | 123 EVERGREEN TERRACE
And here's what I'd like to end up with:
names
----------------------
SMITH INC, JOHN SMITH, JANE SMITH
Any suggestions?
You can't do this easily in MySQL.
The problem is that the relation "is similar to" as you define it is not transitive. In your example, Smith Inc is similar to John Smith (per SSN) and John Smith is similar to Jane Smith (per name), but Smith Inc is not similar to Jane Smith. So there is no single value that all records could be compared with and GROUP BY won't help here.
In other systems which support recursion you could build a transitive closure of this relation which would allow grouping, but this is not an easy task in MySQL.
Like this:
SELECT
name,
ssn,
COUNT(*)
FROM TheTable
GROUP BY
name,
ssn
I've got about 20,000 rows in an INNODB table called 'cards', so FULLTEXT is not an option.
Please consider this table:
id | name | description
----------------------------------------------------------
1 John Smith Just some dude
2 Ted Johnson Another dude
3 Johnathan Todd This guy too
4 Susan Smith Her too
5 Sam John Bond And him
6 John Smith Same guy as num 1, another record
7 John Adams Last guy, promise
So, say the user searches for 'John', I want the result set to be in the order of:
7 John Adams
6 John Smith
3 Johnathan Todd
5 Sam John Bond
2 Ted Johnson
Please note that we've only pulled 'John Smith' once, we took his most recent entry. Due to my data, all names are for the same exact person, no need to worry about 2 different guys named John Smith.
Ideas? Let me know if I can clarify anything.
version 1:
SELECT max(id) id, name
FROM cards
WHERE name like '%John%'
GROUP BY name
ORDER BY CASE WHEN name like 'John %' THEN 0
WHEN name like 'John%' THEN 1
WHEN name like '% John%' THEN 2
ELSE 3
END, name
version 2:
SELECT max(id) id, name
FROM cards
WHERE name like '%John%'
GROUP BY name
ORDER BY CASE WHEN name like 'John%' THEN 0
WHEN name like '% %John% %' THEN 1
WHEN name like '%John' THEN 2
ELSE 3
END, name
I need a MySQL query that will do the following:
Instead of the alpha team names in the 3rd column of the players table, I want it to reference teams.id
table: players
id player_name team
------------------------------------------
1 Sue Smith Silly Chimps
2 Mike Olson Black Cats
3 Tim Hood Silly Chimps
4 Chris Row Grease Monkeys
5 Fred Ware Black Cats
table: teams
id name
-------------------------------
1 Black Cats
2 Grease Monkeys
3 Silly Chimps
So after the Search and Replace update, the players table will look like:
id player_name team
------------------------------------------
1 Sue Smith 3
2 Mike Olson 1
3 Tim Hood 3
4 Chris Row 2
5 Fred Ware 1
The teams table will remain untouched. Let me know if I can clarify anything.
update players, teams set players.team = teams.id where players.team = teams.name