I have two tables and i try to create a table for managing data.
the first table is "questions":
questions (question_id, key1, key2, key3, key4, user_id, creation_date, class, type permission)
and the other:
questions_keys (question_key_id, question_key_name, question_key_refers_to)
every time i push the submit button stored in the table question_keys four records and one in table of questions. heres an example:
question_keys:
1, mathematics, 0
2, history, 1
3, physics, 2
4, geography, 3
and question table:
(1, 1, 2, 3, 4, 8, 2012-12-19 20:41:48, 4, multiple_choice, 0)
the query i need: in the table show the question_key_name where key1, key2, key3, key4 in table questions is equal to question_key_id.
and show in one row something like this:
mathematics, history, physics, geography, multiple_choice, 2012-12-19 20:41:48 etc
i'm new and i need your help.. thanks a lot!
Try this:
SELECT qk1.question_key_name qk2.question_key_name, qk3.question_key_name,
qk4.question_key_name, q.type, q.creation_date
FROM questions q
INNER JOIN question_keys qk1 ON q.key1 = qk1.question_key_id
INNER JOIN question_keys qk2 ON q.key2 = qk2.question_key_id
INNER JOIN question_keys qk3 ON q.key3 = qk3.question_key_id
INNER JOIN question_keys qk4 ON q.key4 = qk4.question_key_id;
You'll have to join the tables four times with this design:
SELECT question_key_name
FROM question_key qk
JOIN questions q on q.key1 = qk.question_key_id
WHERE q.question_id = ?
and then repeat for the other 3. You can UNION them all together, which would return you 4 rows.
As for returning only one row, check out GROUP_CONCAT, but that will return you the question_key_name values as one column. You may be better off combining the 4 rows in your app code.
Related
I have 3 tables in a mysql database that I want to query:
courses (id, course_name)
college_courses (id, college_id, course_id, num_of_courses)
student_courses (id, course_id, college_id)
I am trying to pass an array of course ids to the query and a college id. I want to create a result set to show the name of each course (based on the ids I pass), how many courses the college (e.g. id=8) has access to and how many of each course have been assigned to students. I've tried building a query using joins and sub queries. This is what I have right now but the numbers for courses assigned to colleges and students are all wrong:
SELECT
courses.course_name,
COALESCE(SUM(
CASE
WHEN
college_courses.college_id = 8
THEN
college_courses.num_of_courses
ELSE
0
END
), 0) AS total, COUNT(
CASE
WHEN
student_courses.college_id = 8
THEN
student_courses.id
ELSE
0
END
) AS usedCourses
FROM
courses
LEFT JOIN
college_courses
ON college_courses.course_id = courses.id
LEFT JOIN
student_courses
ON student_courses.course_id = courses.id
WHERE
courses.id IN
(
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
)
GROUP BY
courses.courseid
I have table units in my database. In schema I have fields id, unit_id, group_id, city_id.
For simple I have 3 units:
(1, 1, 1, 1)
(2, 1, 2, 1)
(3, 1, 3, 2)
How can I remove useless groups id, when city id is the same. I have next result:
(1, 1, 1, 1)
(2, 1, 1, 1)
(3, 1, 3, 2)
I know how do this in PHP, but I think 'maybe MySQL has inbuild functions which i don't know' ;)
Regards
if I understand your question correctly you want to all group_id have same value from the same city_id. Basically your first table in question is what you have and the second one is desired result. If that's the case your query could look like this:
UPDATE table1
INNER JOIN (SELECT * FROM table1 GROUP BY city_id) AS tx
ON table1.city_id = tx.city_id
SET table1.group_id = tx.group_id;
Here is the SQL Fiddle to see how it's work.
If you want to completely remove values and to hold only distinct city_id then you can do that with query like this:
DELETE table1 FROM table1
INNER JOIN (SELECT * FROM table1 GROUP BY city_id) AS tx
ON table1.city_id = tx.city_id
WHERE table1.group_id != tx.group_id;
Here is SQL Fiddle for that!
In this case your result table will be without row with id 2...
GL!
If I understand correctly, you want to delete rows where group_id and city_id are equal? If so, it's very simple:
DELETE FROM units WHERE group_id = city_id
Okay, my solution:
UPDATE `ingame_units` INNER JOIN `ingame_groups` g1 ON `ingame_units`.`group_id`=g1.`id` LEFT JOIN `ingame_groups` g2 ON `ingame_units`.`group_id`<>g2.`id` AND g1.`city_id`=g2.`city_id` AND g1.`id`>g2.`id` AND g1.`game_id`=g2.`game_id` SET `ingame_units`.`group_id`=IFNULL(g2.`id`,g1.`id`)
Thanks one man to minus my post and don't try to help me. Regards :)
I am creating a Friend System in my Forum.
I am having a tough time trying to figure out how I would grab users and order by the mutual_friend count.
I am trying to build a page that shows a list of recommended friends.
Here is my structure of tables:
users table
-----
user_id | name |
friends table
-----
friend_id | from_id | to_id
Here is an example of what is happening.
Suppose there are total of A,B,C,D,E,F = 6 people in the site.
I am A, and B,C are my friends.
D and E in turn are friends of B.
D is also a friend of C but E is not a friend of C.
F is not a friend of anyone in the site.
Therefore from above data it looks like D and E are mutual friends of me (A). F is not a mutual friend of mine.
Since D is a friend of both B and C and E is friend of only B:
A and D has 2 mutual friends.
A and E has 1 mutual friend.
A and F has 0 mutual friend.
Now if I want to search (remember i am A) for people who are not my friends I can do something like:
$myfriends = "2,3"; //putting all my friends in a variable
SELECT * FROM users WHERE user_id NOT IN( $myfriends )
But it will yield in terms of user_id ASC .
How can I make it search in DESC order of mutual_friends. ?
I am A i.e user_id = 1
i.e. Person with more mutual friends comes first
Please can anyone show me how can I do this? I have been stuck here for a long while. I searched for lots of thing but can't figure it out.
This query will take the reciprocity of relationships into account, so it doesn't matter if the relationship goes "From A to B" or "From B to A", it will still return the expected result. So given tables like this:
CREATE TABLE people
(`id` int, `name` varchar(1))
;
INSERT INTO people
(`id`, `name`)
VALUES
(1, 'A'),
(2, 'B'),
(3, 'C'),
(4, 'D'),
(5, 'E'),
(6, 'F')
;
CREATE TABLE friends
(`id` int, `personId1` int, `personId2` int)
;
INSERT INTO friends
(`id`, `personId1`, `personId2`)
VALUES
(1, 1, 2),
(2, 3, 1),
(3, 2, 4),
(4, 5, 2),
(5, 3, 4)
;
I believe this is set up as you described: A and B are friends, A and C are friends (notice the inverted relationship), B and D are friends, E and B are friends (another inverted relationship), and C and D are friends.
Assume the id of the person you want is in #personId:
SELECT StrangerId, COUNT(MutualFriendId) AS TotalMutualFriends
FROM
(SELECT
CASE WHEN f.personId2 = mf.friendId THEN f.personId1 ELSE f.personId2 END AS StrangerId,
CASE WHEN f.personId1 = mf.friendId THEN f.personId1 ELSE f.personId2 END AS MutualFriendId
FROM
(SELECT
CASE
WHEN personId1 = #personId THEN personId2
ELSE personId1
END AS friendId
FROM friends
WHERE personId1 = #personId OR personId2 = #personId) AS mf
INNER JOIN friends f
ON (personId1 != #personId AND personId2 = mf.friendId)
OR (personId1 = mf.friendId AND personId2 != #personId)
) AS totals
GROUP BY StrangerId
ORDER BY TotalMutualFriends DESC;
Results for #personId = 1 are:
StrangerId TotalMutualFriends
4 2
5 1
And here is a SQLFiddle to demonstrate (I couldn't get it to allow me to set up a variable, so there is a 1 in its place).
Something like this, perhaps:
Select user_id, friends.to_id, count(friend_of_friend.to_id)
from users left outer join
friends on users.user_id = friends.from_id left outer join
users as friend_user on friends.to_id = friend_user.user_id left outer join
friends as friend_of_friend on friend_user.user_id = friend_of_friend.from_id and friend_of_friend.to_id in (select to_id from friends where from_id = users.user_id)
Group by USER_ID, friends.to_id
Order by 3
Edit for clarity:
The logic of this query depends on joining the same table multiple times. The first two joins are pretty straight-forward, we are starting with a table of users, then joining in the friends table that links each user with all their friends. But then we join in the user table again, but this time using the "to" column - we are getting the user info for each friend. Since we can't have the same table name twice in a query, we give it an alias of "friend_user". Then we join the friends table again, based on the id in the friend_user table - this gives us all the friends of each original user's friends. Then we limit the friends of friends that we get back using the "Friend_of_friend.to_id in ..." to compare the friends of friends to a list of all of the original user's friends, which we bring in by a subquery - the section just after the "in" that is enclosed in parenthesis.
I'm building a form for an award where the nominees can choose multiple award categories to apply to, and answer a series of questions for each award they have chosen.
I have 2 tables.
The first table contains the award categories of the award:
id: 1, 2, 3, ...
name: award1, award2, award3, ....
The second table contains the answers with the nominee id, question id, and award category:
id:
answer_id: 1, 2, 3, ...
nominee_id: 1, 1, 2, ...
question_id: 1,2, 1, ...
category_id: 1, 3, 1, ...
answer: answer 1, answer 2, answer 3, ...
What I need is a query that can display the award categories that the nominee has already submitted answers for, as well as a second query that can display the award categories that are still available for the nominee to apply to.
So using the example above, I would like to see:
nominee_id 1 has already applied to award1 and award 3
nominee_id 1 can still apply for award 2, award 4, ...
EDIT:
Here are the tables, first one is the award categories, second one is the answers
As you can see, nominee with ID of 28 has answered a total of 16 questions, 8 per award category with id of 5 and 6.
The outputs I want are:
a) display the names of the categories nominee 28 has entered in. In this case, Brand Engagement (id:5) and Corporate Social Enterprise (id:6)
b) render a dropdown menu consisting of only the categories nominee 28 has yet to enter. In this case, award category id of 7-8.
Try Queries as below
Query-1
nominee_id 1 has already applied to award1 and award 3
select table1.*,table2.nominee_id,table2.answer_id,table2.question_id,
table2.category_id,table2.answer from table1
inner join table2 on table1.id = table2.category_id
Query-2
nominee_id 1 can still apply for award 2, award 4, ...
select table1.*,table2.nominee_id,table2.answer_id,table2.question_id,
table2.category_id,table2.answer from table1
inner join table2 on table1.id <> table2.category_id
I have assumed fields, please ignore fields not required.
Building on Sameer's answer i would suggest:
First Query (Categories with participation; effectively the same as Sameer's)
SELECT table1.*, table2.nominee_id, table2.answer_id, table2.question_id, table2.category_id, table2.answer
FROM table1
JOIN table2 ON table2.category_id = table1.id
Second Query (Categories with no participation; less "noise")
SELECT table1.*
FROM table1
LEFT JOIN table2 ON table2.category_id = table1.id
WHERE table2.category_id IS NULL
The second query uses the way a LEFT JOIN works: if no matching row is found in table2 all columns are set to NULL inside the result. As the join criteria says table2.category_id = table1.id table2.category_id can only be NULL if table1.id is NULL or there is no row.
I am trying to combine 3 tables into 1 in my database.
My table names = table1, table2, table3
I'm inserting the data into table4
Each table has columns of code, team, p1, p2, p3
IT IS NOT GOING INTO THE DATABASE.
I want the merged insert in the database to look like the following:
code, team, name 1, name 2, name 3, name 4, name 5, name 6, name 7, name 8, name 9
HERE ARE MY TABLES with COLUMNS
table 1: name 1, name 2, name 3
table 2: name 4, name 5, name 6
table 3: name 7, name 8, name 9
This is what I have so far but it is not working. Any help?
INSERT INTO table4
VALUES (code,team,name1,name2,name3,name4,name5,name6,name7,name8,name9)
SELECT table1.code1,
table1.team1,
table1.name1,
table1.name2,
table1.name3,
table2.name4,
table2.name5,
table2.name6,
talbe3.name7,
table3.name8,
table3.name9
FROM table1, table2, table3
WHERE table1.team = table2.team
AND table3.team = table1.team
AND table3.team = table2.team
INSERT INTO table4 VALUES ($code, $team, $name1, $name2, $name3, $name4, $name5, $name6,
$name7, $name8, $name9);
I think you were getting errors because you had a trailing comma after name 9, and you also shouldn't have spaces in the names. Assuming you didnt actually want spaces, we can also optimize your query into proper ANSI syntax:
INSERT INTO table4 (code,team,name1,name2,name3,name4,name5,name6,name7,name8,name9)
SELECT TableOne.code
,TableOne.team
,TableOne.name1
,TableOne.name2
,TableOne.name3
,TableTwo.name4
,TableTwo.name5
,TableTwo.name6
,TableThree.name7
,TableThree.name8
,TableThree.name9
FROM table1 AS TableOne
INNER JOIN table2 AS TableTwo ON TableTwo.team = TableOne.team
INNER JOIN table3 AS TableThree ON TableThree.team = TableTwo.team
The aliases assume code comes from table1. I assume you were getting an ambiguous error for your SELECT of team, on top of the trailing comma after name9.
ok, so dude ... as i understood your question, you are going to merging table or something similar.
Now in you query you are just selecting the data from three table, but nit inserting it into the 4 table.
for that you have to store SELECTED result into variable or array and later on insert it into the 4 table one by one ..
Take a reference of Google; if you stacked some where ...
All the best (Y)