Get results from multiple rows with same names - php

I have some tables with various content. What I want to accomplish is to display the lets say 20 latest entries from those tables in a div.
Here is my first table - audio1
userID folder title date
the two other folders look exactly the same
audio2
userID folder title date
audio3
userID folder title date
How can I get the data from all the tables at the same time and echo them one by one to a div ordered by date with PHP?

SELECT userID, folder, title, date
FROM audio1
UNION ALL
SELECT userID, folder, title, date
FROM audio2
UNION ALL
SELECT userID, folder, title, date
FROM audio3
ORDER BY date DESC LIMIT 20;

Your SQL query will be a 3 part UNION. A UNION query concatenates results from multiple tables with (usually) similar structures, when a JOIN relationship is not needed but rather you just need to return rows from multiple tables.
$sql = "SELECT userID, folder, title, date FROM audio1
UNION ALL
SELECT userID, folder, title, date FROM audio2
UNION ALL
SELECT userID, folder, title, date FROM audio3
LIMIT 20;";
$result = mysql_query($sql);
if ($result) {
// Fetch results and echo them into a list.
}
You will need a column to ORDER BY. This is likely to be date, but you may have other plans. Add an ORDER BY clause before the LIMIT 20.

it seems that your database setup is wrong and you have to have only one table called 'audio' with a field represents the number you are currently using in the table name.

You may try the union, or you can try a join.
SELECT
COALESCE(t1.userID, t2.userID, t3.userID) as userID
, t1.folder, t1.title, t1.date
, t2.folder, t2.title, t2.date
, t3.folder, t3.title, t3.date
FROM table1 t1
FULL OUTER JOIN table2 t2 ON (t1.userID = t2.userID)
FULL OUTER JOIN table3 t3 ON (t1.userID = t3.userID)
It's a very different beast, so I'd thought I'd give you the option.

Related

Query two tables ORDER BY date

So I have two tables that displays values like a Facebook look-a-like feed. They both have a datetime column named date, but I want them to order them together by date DESC.
I think join is the correct way(?), but not quite sure. Can someone help me out?
Currently I have them in two different queries:
$status1 = "1";
$stmt1 = $link->prepare('
SELECT id
, ident_1
, ident_2
, date
, ident_1_points
, ident_2_points
FROM duel
WHERE active=?
ORDER
BY date
');
$stmt1-> bind_param('s', $status1);
and
$status2 = "OK";
$stmt2 = $link->prepare('SELECT id, ident, pp, date FROM sales WHERE status=? AND team IN (2, 3) ORDER BY date DESC LIMIT 20');
$stmt2->bind_param('s', $status2);
How should I do this?
If you want one continuous list containing data from both tables, and the whole thing ordered by date overall, then you might need a UNION query in a subquery, and then order the outer query, something like this:
SELECT *
FROM
(
SELECT id, ident_1, ident_2, date, ident_1_points, ident_2_points
FROM duel
WHERE active=?
UNION ALL
SELECT id, ident, pp, date, NULL, NULL
FROM sales
WHERE status=?
AND team IN (2, 3)
LIMIT 20
) list
ORDER BY date DESC
The requirement isn't 100% clear to be honest from your description (sample data and expected results always helps when asking SQL questions), but I think this is pretty close to what you need.
JOIN doesn't seem appropriate, unless you want a result set where items from each table are linked to each other by some common field, and you combine them such that you get all the columns side by side, showing the data from one table next to the data which matches from the other table.
If you're unsure, I suggest looking at tutorials / examples / documentation which show what JOIN does, and what UNION does.

SQL: How do I filter (WHERE) a joined (ON) table in SQL?

I have two tables (users and posts) and I want to write out all posts (among other things) by one user. I'm thinking I should use a JOIN and WHERE but I get an error for using WHERE.
This is my code:
SELECT username, post, joinDate, title, info FROM users
WHERE userId='18'
JOIN posts ON users.userId=posts.userId
ORDER BY date DESC
I'm new to this and perhaps there is a better way but I can't figure it out atm.
Thankful for all answers!
The JOIN clause comes before the WHERE clause, after the FROM clause. First you join together all the tables you need, then you do your filtering with WHERE. Like this:
SELECT username, post, joinDate, title, info
FROM users
JOIN posts ON users.userId=posts.userId
WHERE users.userId='18'
ORDER BY date DESC
try like below
SELECT u.*,p.*
FROM users u JOIN posts p ON u.userId=p.userId
WHERE u.userId=18
ORDER BY date DESC
where will be after join and 18 is int datatype value so not need single quote for this and use alias for avoiding ambigous column name
SELECT username, post, joinDate, title, info
FROM users
JOIN posts ON users.userId=posts.userId and users.userId='18'
ORDER BY date DESC
if userId is in users table then YES you can use where userId='18'.
If userId is in posts table then it should be userId='18' be in join part.

Select users with more than one instance in database

I have a table with a userID field and an itemID field. I would like to select all of those users that have two or more instances where itemID is the same (that is, if for example there are 3 records where userID = 1 and itemID = 7 then I would like those results, but not if there's just one instance). I need to get all users (not just results for a certain userID).
Can anybody suggest how I could do this?
Thanks.
You can do this using aggregation and a having clause. If you just want the users:
select distinct userID
from t
group by userId, itemID
having count(*) >= 2;
This is an interesting query because it is one of the very rare situations where group by and select distinct are used together. If you wanted the userId/itemId pairs, then you would use select userId, itemId, without the distinct.
You just need to use group by and having. The having clause is like where except that it also works on aggregations. So it's something like select userID, itemID, count(*) from mytable group by userID, itemID having count(*) > 1.

Limit the output of a mysql query when a variable is used in WHERE

I have a mysql statement that queries a database for the latest track. However, since the database is partially normalized the ID's are in different tables. In the query's I get the artist ID'd from the artists table and put them into a variable. The variable in then parsed into a query that looks at the tracks to find the latest one, this is where the problem lies. Since the $artist variable can have tonnes of ID's in, all those ID's are parsed into the query and the outcome is several url's put together even though I have put a LIMIT on the query.
Bear in mind that I cannot LIMIT the artist query as I need to get all the artists from the table and find the latest track out of all the artists.
How would I get just the latest url from the query without limiting the artist query?
//Set up artist query so only NBS artists are chose
$findartist = mysql_query("SELECT * FROM artists") or die(mysql_error());
while ($artist = mysql_fetch_array($findartist)){
$artist = $artist['ID'];
//get track url
$fetchurl = mysql_query("SELECT * FROM tracks WHERE id = '$artist' ORDER BY timestamp DESC LIMIT 1");
url = mysql_fetch_array($fetchurl);
$track_ID = $url ['ID'];
$trackname = $url ['name'];
$trackurl = $url ['url'];
$artist_ID =$url['ID'];
}
ADDITION:
$findartist = mysql_query("SELECT A.*, T.*
FROM (
SELECT T.ARTIST_ID, MIN(T.TRACK_ID) TRACK_ID
FROM (
SELECT ARTIST_ID, MAX(`TIMESTAMP`) `TIMESTAMP`
FROM TRACKS
GROUP BY ARTIST_ID
) L
JOIN TRACKS T ON ( L.ARTIST_ID = T.ARTIST_ID
AND L.`TIMESTAMP` = T.`TIMESTAMP`)
GROUP BY T.ARTIST_ID
) X
JOIN ARTISTS A ON X.ARTIST_ID = A.ARTIST_ID
JOIN TRACKS T ON (X.TRACK_ID = T.TRACK_ID AND X.ARTIST_ID = T.ARTIST_ID)
ORDER BY A.NAME");
while ($artist = mysql_fetch_array($findartist)){
$artist = $artist['ID'];
$trackurl = $artist['url'];
The relation between artists table and tracks table is one-to-many. So your tracks table should have a column artist_id and foreign key constraint which cross-references this column with id column in artists table. When this is done, the query to get latest tracks would look like:
SELECT id, name, url, MAX(timestamp) timestamp
FROM tracks
GROUP BY artist_id
If I understand you correctly, you want the latest (most recent timestamp) track from each artist in your artist table.
It would help if you had your table definitions displayed. I think you're confusing ARTIST_ID and TRACK_ID in your query from your tracks table. So I will use the column names ARTIST_ID and TRACK_ID throughout.
(TIMESTAMP is an unfortunate choice for a column name, because it's also a MySQL data type name, by the way. No matter.)
You can do this with one query. Let us construct that query. It's not super simple but it will work just fine.
First, let's get the timestamp of the latest track or tracks by each artist. This returns a virtual table with ARTISTS_ID and latest TIMESTAMP shown.
SELECT ARTIST_ID, MAX(`TIMESTAMP`) `TIMESTAMP`
FROM TRACKS
GROUP BY ARTIST_ID
Now, let's nest that query into another query to come up with a particular track_id that is the latest track from each artist. It is necessary to disambiguate the situation where an artist has more than one track with precisely the same timestamp. In this case we'll grab the lowest numbered TRACK_ID.
I suppose that all the tracks on an album by an artist have the same timestamp, but they have ascending track IDs, so this picks the first track on the artist's latest album.
SELECT T.ARTIST_ID, MIN(T.TRACK_ID) TRACK_ID
FROM (
SELECT ARTIST_ID, MAX(`TIMESTAMP`) `TIMESTAMP`
FROM TRACKS
GROUP BY ARTIST_ID
) L
JOIN TRACKS T ON ( L.ARTIST_ID = T.ARTIST_ID
AND L.`TIMESTAMP` = T.`TIMESTAMP`)
GROUP BY T.ARTIST_ID
See how this goes? The inner subquery finds the latest timestamp for each artist, and the outer query uses the subquery to find the lowest-numbered track ID for that artist and timestamp. So, now we have a virtual table that shows the latest track_id for each artist.
Finally, we need to query the joined-together artist and track information to get your list of artists and their latest tracks. We'll join the two physical tables with the virtual table we just figured out.
SELECT A.*, T.*
FROM (
SELECT T.ARTIST_ID, MIN(T.TRACK_ID) TRACK_ID
FROM (
SELECT ARTIST_ID, MAX(`TIMESTAMP`) `TIMESTAMP`
FROM TRACKS
GROUP BY ARTIST_ID
) L
JOIN TRACKS T ON ( L.ARTIST_ID = T.ARTIST_ID
AND L.`TIMESTAMP` = T.`TIMESTAMP`)
GROUP BY T.ARTIST_ID
) X
JOIN ARTISTS A ON X.ARTIST_ID = A.ARTIST_ID
JOIN TRACKS T ON (X.TRACK_ID = T.TRACK_ID AND X.ARTIST_ID = T.ARTIST_ID)
ORDER BY A.NAME
Think of it this way: You have some physical tables with your data in them. You can also create virtual tables with subqueries and use them as if they were physical tables by including them, nested, in your queries. That nesting is one of the reasons it's called Structured Query Language.
You're going to need indexes on your TIMESTAMP, ARTIST_ID, and TRACK_ID columns for this to work efficiently.
Edit:
There really isn't sufficient information about your schema in your question to figure out how unambiguously to get the most recently uploaded track.
If the TRACK_ID is the autoincrementing primary key for the TRACKS table, it's easy. Get the highest numbered track ID left joined to the artist (left joined in case there's no corresponding row in the artist table).
SELECT T.*, A.*
FROM TRACKS T
LEFT JOIN ARTISTS A ON T.ARTIST_ID = A.ARTIST_ID
ORDER BY T.TRACK_ID DESC
LIMIT 1
If TRACK_ID isn't an autoincrementing primary key but you almost never have two timestamps the same, do this. If there happen to be two or more tracks with the same timestamp, it will arbitrarily select one of them.
SELECT T.*, A.*
FROM TRACKS T
LEFT JOIN ARTISTS A ON T.ARTIST_ID = A.ARTIST_ID
ORDER BY T.`TIMESTAMP` DESC
LIMIT 1
The trick to this data stuff is to be very careful to specify exactly what you want. It's pretty clear from your question that you're trying, in a loop, to get the most recent track for each artist in turn. My query did that without a loop in your program. But, you know what, I don't know the names of all your columns so my SQL might not be perfect.
Big thanks to #OllieJones and #hookman for helping me out on this. I have found the query I need and I have done it all in one query without any PHP so big thanks to them both.
Anyway here it is;
SELECT T.url, A.ID, T.ID
FROM tracks T
LEFT JOIN ARTISTS A ON T.ID = A.ID
WHERE T.ID = A.ID
ORDER BY T.timestamp DESC
LIMIT 1
I took much of #OllieJones query and edited it a bit. I added the WHERE clause so that only artists are chosen and took away the * so only the needed data is returned. I also took #hookman advice and used a load of foreign keys. Gonna help a lot in the future.

Need to check which row has most likes between two tables

I'm fairly new to MYSQL!
I need to make a SQL query where i check how many likes a row has (between two tables)
I found another question that looked like mine, but i can't get it to return anything (even though it doesn't create an error.
query:
SELECT *
FROM likes
INNER JOIN (SELECT likes.like_id,
COUNT(*) AS likes
FROM likes
INNER JOIN uploads ON likes.upload_id=uploads.upload_id
WHERE uploads.upload_date >= DATE_SUB(CURDATE(), INTERVAL 8 DAY)
GROUP BY uploads.upload_id) x ON x.like_id = likes.like_id
ORDER BY x.likes DESC
Link to the original question:
MySQL, Need to select rows that has the most frequent values in another table
Help is much appreciated
Kind regards,
Mathias
Since you didn't post your table structure I'll have to guess..
select someid, count(*) cnt from
(
select * from table1 t1 join table2 t2 on t1.someid = t2.someid
) as q0 group by someid order by cnt desc;
It will need tweaking to fit your schema.

Categories