My query doesn't work. What can I do? [duplicate] - php

This question already has answers here:
Can I concatenate multiple MySQL rows into one field?
(16 answers)
Closed 8 years ago.
I would like to display a <table> with these <th>-s:
project title
description
status
start date
end date
users
The problem is, that my subquery returns more than 1 row.
Usually 4 people belong to a project, an owner, a manager, a developer and a tester. The owner can create new projects, so he can see the project table I would like to create, but I can't put the users at the end of the table, because more than one belongs to every row.
This is the query:
SELECT project.id, title, description, status, start,end
FROM project
LEFT JOIN users ON (SELECT userid FROM roles,project WHERE projectid=project.id)=users.id
My tables are:
PROJECT
id
title
description
status
start
end
USERS
id
name
pass
email
ROLES
id
projectid
userid
rolename

Try join all tables instead of subquery like this :
SELECT project.id, title, description, status, start,`end` ,GROUP_CONCAT( users.name) AS usernames
FROM project
LEFT JOIN roles On roles.projectid = project.id
LEFT JOIN users ON roles.userid =users.id
GROUP BY project.id

Use an IN clause, e.g.
JOIN users ON users.id IN (SELECT userid FROM ....)
= is for comparing two single values. IN is used to check if a single value is in a set of values.

I assume you want all the users in a cell of your result table but only one copy of the other fields in their cells. If you really want this in one table you need to parse the results in code. Use a query that has all the fields you want like so:
SELECT project.id, title, description, status, start,end, users.name
FROM project
LEFT JOIN roles On roles.projectId = project.id
LEFT JOIN users ON roles.userId = users.id
Then in your code check for the duplicates and don't display them. Pseudo code example:
loop over all result rows {
if( new_id <> old_id ){
if not first row close your previous row </tr>
display <tr>
display all the fields
}else{
only display the addition of the user name (with a <br> or whatever to separate)
}
}
close your last row </tr>
This will probably display it the way you want but the data is not aligned for one table of display. Consider a link to show the user list as a popup DIV.

Related

SELECT loop within SELECT loop [duplicate]

This question already has answers here:
MySQL Results as comma separated list
(4 answers)
Closed 4 years ago.
I have a PHP/MySQL scenario where I want to display a list of events but also show all users assigned to an event. In MySQL I have an events, eventusers and users tables.
I can SELECT event_id, event_name FROM events then loop through results in PHP and then SELECT user_id FROM eventusers WHERE event=[event_id] in each result loop to get that particular event's users.
I am wondering if there is way to do this in one single SQL query (and it's also performance decent) so I get data from the events table as well as all the user IDs attached to the event from the eventusers table. Something like:
event id | event name | Users from eventusers table
------------------------------------------
1 | Soccer match | 3,56,79
2 | Cycling | 46,77,88,126,78
You should make use of a JOIN statement, which merges your tables:
SELECT column_name(s)
FROM table1
INNER JOIN table2 ON table1.column_name = table2.column_name;
In your case, you should do something like:
SELECT event_name, user
FROM events
INNER JOIN eventusers
ON events.event_id = eventusers.event_id
I hope this is helpful for you
You can use the join function:
select * from
table1 JOIN table2
ON table1.pk=table2.fk
and then add the condition
where table1.column= something
however you need to have both tables joined with a column (.pk and .fk), in this case it could be the eventuserid
select * from
events JOIN eventusers
ON events.eventuserid=eventusers.userid
where event.id= [event_id]
Also you can subtitue the * with the columns you'll need: tablename.column and youll only get those column values in return
I'm sorry I dont understand the second part about the CSV file, can you clarify?

Mysql - Verify if part of a result exists in another table

I have two tables in Mysql, one is all the data I need to display to users and in another simply a list of URLs of the items that were deleted.
What I want to do is select all the results as long as the element does not exist in the "deleted items" table.
In my table of "Deleted_Items" I have a list of URLs of the type
https://example.com/video/123456/
But in my table "Items" the URL column contains the following:
https://example.com/video/123456/dogs_and_cats/
I would need to do something like this (pseudocode):
SELECT id, url, thumb FROM Items
WHERE Items.url NOT CONTAINS Deleted_Items.url
P.S:
I had a similar case with two other tables but the difference was that in the "Items" table I had a list of IDs and in the "Deleted_Items" table I also had a list of IDs, so I applied the following query:
SELECT id, url, thumb
FROM Items
LEFT OUTER JOIN Deleted_Items
ON (Items.url = Deleted_Items.url)
WHERE Deleted_Items.url IS NULL
LIMIT 30
You could use a left join check for deleted_item.url is null
SELECT Items.id, Items.url, .Itemsthumb
FROM Items
LEFT JOIN deleted_Items ON Items.url = deleted_Items.url
where deleted_Items.url is null
looking to your added data sample could be you need a like comparision
SELECT Items.id, Items.url, .Itemsthumb
FROM Items
LEFT JOIN deleted_Items ON deleted_Items.url like concat(Items.url , '%')
where deleted_Items.url is null

How to get 1 row per user with INNER JOIN

I have two tables one is user and another is images. I gave users the option to select multiple images. I can store multiple images with same user_id in database, but when I am trying to get one image from every user I am getting all the images.
My query is something like this:
$query = "
SELECT *
FROM images i
JOIN users u
ON u.user_id = i.user_id
LIMIT 1";
When I run this query in while() loop, I only get very first image from images table.
I am really sorry if I am not able to clarify what I am try to ask.
Have you tried something like this:
SELECT * FROM users u INNER JOIN images i ON u.user_id = i.user_id GROUP BY u.user_id;
This should return you only one record from user/image tables for each user that has an image.
Don't run queries in a while loop. Instead, use one query to get all the desired records.
If you insist on running your query in a loop, then you are missing WHERE users.user_id = ? part in your query, so you can get a different result for each user in a loop.
you can do this without using join. simple select user and fetch data and on the bases of 'id' add query to get image. i hope this will help you;
Your current query:-
SELECT *
FROM images i
JOIN users u
ON u.user_id = i.user_id
LIMIT 1
uses LIMIT 1. This tells the query to bring back 1 row.
Removing the LIMIT 1 will return 1 or more records per user (who has at least 1 image), one for each image.
If you want a single user then it is possible (although not recommended) to (ab)use the GROUP BY clause:-
SELECT *
FROM images i
JOIN users u
ON u.user_id = i.user_id
GROUP BY u.user_id
This would bring back one record per user, but which image it returns is not defined. It could bring back the first image for that user, or the last one, or any other one (and which one it returns could change in the future). Further, there is no actual reason it couldn't return values from different rows for each of the columns on the images table (unlikely, but nothing specified to stop this happening).
Note that basic SQL standards specify (with a small exception) that any non aggregate field brought back in a SELECT statement must be in the GROUP BY clause. MySQL used to not enforce this restriction by default, but recently this changed and it is enforced by default. As such by default this query would no longer work as it is returning all the fields from the images and users tables while only specifying the user_id from the users table in the GROUP BY clause.
What you should do is define which image you want for each user. Assuming the first image (and that the images table uses an auto increment primary key called id):-
SELECT u.*,
i.*
FROM users u
LEFT OUTER JOIN
(
SELECT user_id
MIN(id) AS first_image_id
FROM images
GROUP BY user_id
) sub0
ON u.user_id = sub0.user_id
LEFT OUTER JOIN images i
ON sub0.user_id = i.user_id AND sub0.first_image_id = i.id
This uses a sub query to get the first image id for each user. Then that is joined to the images table to get the other details for that image from the images table.
Note I have used LEFT OUTER JOIN. This is to return a row for a user who doesn't have any images uploaded.
Note it is generally a bad idea to use SELECT *, rather than specifying the columns to be returned. I have left this in place here as I do not know the column names of your tables.

Mysql table join, but return values if first table has information, but second doesnt

I have the following mysql query
SELECT Name, Summoner_Name, ROUND(SUM(timePlayed)/60) as Total_Time
FROM UserNames, games_database
WHERE (UserNames.ID = games_database.UserNames_ID AND
UserNames.ID IN ({$Member_Ids_Sql}))
GROUP BY UserNames.ID
ORDER BY Total_Time DESC;
It effectively will grab the players name, summoner names, and total play_time. It does this by using a table join. As one table Usernames, contains the users ID, Name and Summoner Name. Where as the Games_database table holds every game the player has played.
What I want to do is display the information of users that are in the UserNames table, but haven't played any games yet.
Extra Information:
UserNames Database contains
ID, Summoner_ID, Summoner_Name, Name
Games_database Database contains
ID, Match_ID, my_Date, timePlayed, champion, win, Summoner_ID, UserNames_ID, Game_Type
I got this working perfectly for all users with games, but when a new user enters the system, they aren't shown in this query due to no games being played.
You want a left join to find non-matches:
SELECT Name, Summoner_Name, ROUND(SUM(timePlayed)/60) as Total_Time
FROM UserNames LEFT JOIN
games_database
ON UserNames.ID = games_database.UserNames_ID
WHERE UserNames.ID IN ({$Member_Ids_Sql}) AND
games_database.UserNames_ID is null
GROUP BY UserNames.ID
ORDER BY Total_Time DESC;
Note: you should learn to always use explicit join syntax.
What you need here is a left outer join. A left outer join will return all results in the first table (filleted by your where) with the results in the second table. If there are no matches a null will be shown.

Mysql relationships and getting linked data

I have been doing this for a while now, via some php, first lets say we have two tables:
Users
user_id name email
Images
image_id user_id url
user_id and user_id from images table would be linked with a relationship.
Now what I would do is select the user by their Id, check if the user is found, if so then make another query to images table, and check for num rows and loop through the return, is there a function that I could use that would allow me to just select the user and all the images that are linked to the user without doing a joint query.
Thank you for any help
When you say "without doing a joint query" I think you mean "without doing two queries."
In fact, what you want is probably a LEFT JOIN. The idea is that you select users from the user table matching some ID, and LEFT JOIN the images table. The left join will give you null values if no images exist for the user. If you use a normal join, the fact that no matching records exist in the images table will result in no rows returned.
Here is an example:
SELECT u.name, u.email, i.url
FROM Users u
LEFT JOIN Images i ON (i.user_id = u.user_id)
WHERE u.id = #SpecificUserID;
Assuming the user id is found and there are some images for that user, you will get a result that looks like this:
name email url
----- ----- -----
John j#a.com abc.jpg
John j#a.com def.jpg
John j#a.com ghi.jpg
Now as you can see, the name and email values keep repeating. You get a unique image url for each row and the matching username and email.
If you only select one user at a time, this is simple to process in a loop. On the first iteration read all three values. On subsequent iterations just read the url, adding it to your list or array.
Here is a useful tutorial on joins: Understanding JOINs in MySQL and Other Relational Databases
This can be done in one query rather than two by using an inner join to get your result set.
$sql = "SELECT u.user_nid, i.url
FROM tbl_user u
INNER JOIN i.user_nid = u.user_nid
WHERE user_nid = ?"
With this query you will receive a list of the users images and if there are no images returned or the user does not exist, than you will have a row return of zero.
You'll have to use a join to retrieve data from multiple tables in a single query.
The foreign key relationships enforce constraints. Ex: You can't insert a record into Table A referring to a key in Table B without the record actually being in Table B.

Categories