I get the following Error below from my query, and was wondering how can I fix this problem?
Duplicate column name 'user_id'
Here is My MySQL query.
"SELECT COUNT(users_friends.user_id) FROM ((SELECT *
FROM users_friends
INNER JOIN users ON users_friends.user_id = users.user_id
WHERE users_friends.user_id = '" . $user_id . "'
AND users_friends.friendship_status = '1')
UNION
(SELECT *
FROM users_friends
INNER JOIN users ON users_friends.friend_id = users.user_id
WHERE users_friends.friend_id = '" . $user_id . "'
AND users_friends.friendship_status = '1')) as friends"
Here is my new query.
SELECT COUNT(user_id) FROM ((SELECT users_friends.user_id
FROM users_friends
INNER JOIN users ON users_friends.user_id = users.user_id
WHERE users_friends.user_id = '" . $user_id . "'
AND users_friends.friendship_status = '1')
UNION
(SELECT users_friends.user_id
FROM users_friends
INNER JOIN users ON users_friends.friend_id = users.user_id
WHERE users_friends.friend_id = '" . $user_id . "'
AND users_friends.friendship_status = '1')) as friends
There's a couple of problems here. You obviously (read humor) only want a row count, so no need to SELECT *, true? I'm assuming you want to use a UNION to add rows together... Thus:
SELECT COUNT(*) AS the_count
FROM
(SELECT user_id AS ID
FROM users_friends
INNER JOIN users ON users_friends.user_id = users.user_id
WHERE users_friends.user_id = '" . $user_id . "'
AND users_friends.friendship_status = '1'
UNION
SELECT friend_id AS ID
FROM users_friends
INNER JOIN users ON users_friends.friend_id = users.user_id
WHERE users_friends.friend_id = '" . $user_id . "'
AND users_friends.friendship_status = '1'
) AS uf1;
Note: I'm assuming that the rest of the query (inner join, where, etc) works.
Edited, fixing the syntax problem with the ambiguous field names for ya.
SELECT COUNT(*) AS the_count
FROM
(SELECT uf.user_id AS ID
FROM users_friends uf
INNER JOIN users u ON uf.user_id = u.user_id
WHERE uf.user_id = '" . $user_id . "'
AND uf.friendship_status = '1'
UNION
SELECT uf.friend_id AS ID
FROM users_friends uf
INNER JOIN users u ON uf.friend_id = u.user_id
WHERE uf.friend_id = '" . $user_id . "'
AND uf.friendship_status = '1'
) AS uf1;
You are using SELECT * from , bringing all columns from 2 tables user_friends and users, both of them have a column called user_id. When you use a UNION it is my understanding that a temporary table is created, so MySQL is complaining that you have 2 columns with the same name. Try to explictly define the user_id you want to use for instance SELECT users.user_id, user_friends.abc etc
Edit:
If i understand this correctly, you are trying to get user ids of the friends.To me it seems like your previous query would return the $user_id in all records.
Try this:
SELECT COUNT(*) as CNT FROM
(
(SELECT users.user_id as uid
FROM users_friends
JOIN users ON users_friends.user_id = users.user_id
WHERE users_friends.friend_id = '" . $user_id . "'
AND users_friends.friendship_status = '1')
UNION
(SELECT users.user_id as uid
FROM users_friends
JOIN users ON users_friends.friend_id = users.user_id
WHERE users_friends.user_id = '" . $user_id . "'
AND users_friends.friendship_status = '1')
) as myfriends
Related
I have the following SQL:
SELECT (
(SELECT SUM(vote_score)
FROM question_votes
JOIN questions
ON vote_question = q_id
JOIN users
ON q_author = users.id
WHERE q_author` = users.id)
+
(SELECT SUM(vote_score)
FROM answer_votes
JOIN answers
ON vote_answer = a_id
JOIN users
ON a_author = users.id
WHERE a_author = users.id)) AS rep
and I want it to be added here (Ion Auth's method):
$this->db->select(
array(
$this->tables['users'].'.*',
$this->tables['groups'].'.name AS '. $this->db->protect_identifiers('group'),
$this->tables['groups'].'.description AS '. $this->db->protect_identifiers('group_description'),
"(SELECT COUNT(`a_author`) FROM `answers` WHERE a_author = users.id) + (SELECT COUNT(`q_author`) FROM `questions` WHERE q_author = users.id ) AS total_posts",
"SELECT
((SELECT SUM(vote_score)
FROM question_votes
JOIN questions
ON vote_question = q_id
JOIN users
ON q_author = users.id
WHERE q_author` = users.id)
+
(SELECT SUM(vote_score)
FROM answer_votes
JOIN answers
ON vote_answer = a_id
JOIN users
ON a_author = users.id
WHERE a_author = users.id)) AS rep"
)
);
but I get the followin error:
Did you read the error message?
You have a (`) where shouldn't be any.
Change this: WHERE q_author' = users.id for this: WHERE q_author = users.id
I have this query that uses a UNION:
$this->db->query('
SELECT DISTINCT users.user_pic, users.id, users.username, contacts.accepted
FROM users
LEFT JOIN contacts ON users.id = contacts.user_1
WHERE contacts.user_2 = ' . $this->session->userdata('user_id') . '
UNION DISTINCT
SELECT DISTINCT users.user_pic, users.id, users.username, contacts.accepted
FROM users
LEFT JOIN contacts ON users.id = contacts.user_2
WHERE user_1 = ' . $this->session->userdata('user_id')
);
Is there a way to see if the sessions 'user_id' was encountered in contacts.user_1 or contacts.user_2? Maybe by changing the query, or if i can use some if statements in the view?
Thanks in advance
George
yes you can add another field to select , that you can recognise like (1,2)
$this->db->query('
SELECT 1 as table_id,DISTINCT users.user_pic, users.id, users.username, contacts.accepted
FROM users
LEFT JOIN contacts ON users.id = contacts.user_1
WHERE contacts.user_2 = ' . $this->session->userdata('user_id') . '
UNION DISTINCT
SELECT 2 as table_id,DISTINCT users.user_pic, users.id, users.username, contacts.accepted
FROM users
LEFT JOIN contacts ON users.id = contacts.user_2
WHERE user_1 = ' . $this->session->userdata('user_id')
);
I typically use:
$id = $this->session->userdata('user_id');
then use $id in the query. Reads cleaner and on MySQL at least, if the query fails, it lists the value of $id. Never tried calling the session in the query before.
I have a list of venues in the Venues table, and a list of a cities/states in the Locations table. The venue is associated with an area code unique to my organization, referred to as a SOYID. The SOYID is made up of a geographical area - each row in the Locations table has a City, State, and the corresponding SOYID. Some Venues rows have a SOYID, others do not; for those that do not, I need to find the SOYID for the city and state listed. I only want to select those Venues in a specific SOYID.
This query works, however, it takes a few seconds to load; I don't think I am writing the query correctly. Currently Venues has approx 140 rows, Locations has 40,000.
$sql = "SELECT DISTINCT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr
FROM Venues AS a LEFT JOIN Locations AS c ON a.City = c.city
WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "'
OR ((c.city = a.City) AND (c.state = a.StateAbbr) AND (c.SOYID = '" . mysql_real_escape_string($SOYID) . "'))
ORDER BY a.Name ASC";
Any time you reference a column from a LEFT JOINed table (c.state and c.SOYID in your specific case) in the WHERE clause, you force that join to behave like an INNER JOIN. Instead, make those tests part of the join condition:
"SELECT DISTINCT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr
FROM Venues AS a
LEFT JOIN Locations AS c
ON a.City = c.city
AND a.StateAbbr = c.state
AND c.SOYID = '" . mysql_real_escape_string($SOYID) . "'
WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "'
OR c.SOYID IS NOT NULL /* LEFT JOIN found a matching row */
ORDER BY a.Name ASC"
EDIT: Based on comments, this version should allow you do remove the DISTINCT requirement:
"SELECT a.VenueID, a.Name, a.PhotoID, a.City, a.StateAbbr
FROM Venues AS a
WHERE a.SOYID = '" . mysql_real_escape_string($SOYID) . "'
OR EXISTS(SELECT NULL
FROM Locations AS c
WHERE a.City = c.city
AND a.StateAbbr = c.state
AND c.SOYID = '" . mysql_real_escape_string($SOYID) . "')
ORDER BY a.Name ASC"
When I set my pagination to display 10 comments at a time my comments query wont count the comments replies as part of the display count how can I fix this so that my comments replies are counted? My comments replies queries are nested in my main query to display comments.
Query for pagination
SELECT COUNT(comment_id) FROM comments WHERE id = $id
The main query to display comments.
$dbc = mysqli_query($mysqli,"SELECT comments.*, users.*
FROM comments
LEFT JOIN users
ON comments.user_id = users.user_id
WHERE id = '" . $id . "'
AND parent_comment_id = 0
LIMIT $start, $display");
The main querys reply comments.
//display comments replies
$dbc2 = mysqli_query($mysqli, "SELECT comments.*, users.*
FROM comments
LEFT JOIN users
ON comments.user_id = users.user_id
WHERE id = '" . $id . "'
AND parent_comment_id >= 1");
//display comments replies
$dbc3 = mysqli_query($mysqli, "SELECT comments.*, users.*
FROM comments
LEFT JOIN users
ON comments.user_id = users.user_id
WHERE id = '" . $id . "'
AND parent_comment_id >= 1");
Maybe this query, could you give the precise DB structure to work with.
SELECT
com1.*,
users.*,
(
SELECT COUNT(*)
FROM comments AS com2
WHERE com2.parent_comment_id = com1.id
) AS num_replies
FROM comments AS com1
LEFT JOIN users ON com1.user_id = users.user_id
WHERE
com1.id = '" . $id . "'
AND com1.parent_comment_id = 0
LIMIT $start, $display
What I ended up doing was taking two SQL queries and using the array_intersect() in PHP to filter out the results:
$sql1 = 'SELECT z.*, u.username, u.user_colour, u.username_clean, u.user_avatar, u.user_avatar_type
FROM ' . ZEBRA_TABLE . ' z, ' . USERS_TABLE . ' u
WHERE (( z.user_id = ' . $user->data['user_id'] . '
AND z.friend = 1
AND u.user_id = z.zebra_id )
OR ( z.zebra_id = ' . $user->data['user_id'] . '
AND z.friend = 1
AND u.user_id = z.user_id ))
ORDER BY u.username_clean ASC';
$sql2 = 'SELECT z.*, u.username, u.user_colour, u.username_clean, u.user_avatar, u.user_avatar_type
FROM ' . ZEBRA_TABLE . ' z, ' . USERS_TABLE . ' u
WHERE (( z.user_id = ' . $user_id . '
AND z.friend = 1
AND u.user_id = z.zebra_id )
OR ( z.zebra_id = ' . $user_id . '
AND z.friend = 1
AND u.user_id = z.user_id ))
ORDER BY u.username_clean ASC';
The structure of both queries are the same and the only difference is $user->data['user_id] (first person) is replaced with $user_id (second person) in the second query. I want to retrieve friends that both users have in common. Could anyone merge this into a single query so that I don't have to use two queries and call array_intersect()?
Well, you could always just subquery both:
$sql = 'SELECT a.*
FROM ('.$sql1.') AS a
JOIN ('.$sql2.') AS b ON a.user_id = b.user_id AND a.username = b.username';
You may want to add u.user_id to the field list of both queries u.user_id AS u_user_id then change the second join clause from a.username = b.username to a.u_user_id = b.u_user_id...
EDIT: Now that I really look at it closer, those two queries are almost identical... Why not just do something like this (replace the where clause to this):
WHERE z.friend = 1
AND (
( z.user_id = '.$user_id.' AND u.user_id = z.zebra_id )
OR
(z.zebra_id = '.$user_id.' AND u.user_id = z.user_id )
) AND (
( z.user_id = '.$user->data['user_id'].' AND u.user_id = z.zebra_id )
OR
(z.zebra_id = '.$user->data['user_id'].' AND u.user_id = z.user_id )
)
That should give you the result of both queries intersected, and be faster since it can optimize better (hopefully)...
Oh, and they are in different where blocks because there's a few cases where z.user_id matches $user_id, but z.zebra_id matches $user->data['user_id']... So rather than list all the permutations, I just layed it out like this...
You could select users who are friends with both users by linking the user table to the zebra table twice:
SELECT u.username, u.user_colour, u.username_clean, u.user_avatar, u.user_avatar_type
FROM users u
JOIN zebra z1 ON z1.friend=1 AND (
(u.user_id = z1.user_id AND z1.zebra_id = #user_id1)
OR (u.user_id = z1.zebra_id AND z1.user_id = #user_id1)
)
JOIN zebra z2 ON z2.friend=1 AND (
(u.user_id = z2.user_id AND z2.zebra_id = #user_id2)
OR (u.user_id = z2.zebra_id AND z2.user_id = #user_id2)
)
ORDER BY u.username_clean ASC
The JOIN takes all the rows from the users table, and all the rows from the zebra table, and looks for the combinations that satisfy the ON clause. In this case, the first join finds all users who are friends with #user_id1, the second join further restricts it to users who are also friends with #user_id2.
This query will perform much faster than using subqueries will. The query would be even faster if the zebra table stored friendships in both directions, allowing you to take more advantage of table indexes, and you could remove the OR portion of the ON clauses:
SELECT u.username, u.user_colour, u.username_clean, u.user_avatar, u.user_avatar_type
FROM users u
JOIN zebra z1 ON u.user_id = z1.user_id AND z1.friend=1 AND z1.zebra_id = #user_id1
JOIN zebra z2 ON u.user_id = z2.user_id AND z2.friend=1 AND z2.zebra_id = #user_id2
ORDER BY u.username_clean ASC