Applying filter using SQL Join - php

My website is a Q&A site like stackoverflow.com. When a user creates a question, he has the ability to tags it. Later, when he need to find all questions which belongs to a category, he can use the filter box which accepts tag names. Based on user entries, i will just refresh the job list.
My table design is like below
Table: Questions
id | QuestionTitle |Other details|
----------------------------------|-------------|
1 | Why is earth round? |
2 | How much is moon's diameter? |
Table: Tags
id | tagname
----------------
1 | planets
2 | earth
3 | moon
Table: AttachedTags
id | question_id | tag_id
-------------------------
1 | 1 |2
2 | 1 |1
3 | 2 |3
In the PHP/Controller i will get tag id's as user input's in the filter box.
What is the best method to fetch all those questions under a particular tag?
I have used the following query, but it is retrieving a job two times, because a job can have more than one category.
SELECT
Questions.id,
Questions.jobtitle,
AttachedTags.tag_id
FROM
Questions INNER JOIN
AttachedTags ON Questions.id = AttachedTags.question_id
WHERE
AttachedTags.tag_id IN (1,2)

Isn't it enough to add a distinct to filter out duplications and remove tag_id from the select?
SELECT DISTINCT
Questions.id,
Questions.jobtitle
FROM
Questions INNER JOIN
AttachedTags ON Questions.id = AttachedTags.question_id
WHERE
AttachedTags.tag_id IN (1,2)

Related

Querying more than 1 table in a single query via JOIN

I cannot quiet get using the JOIN clause around my head, even after I have ready multiple posts on the topic.
Here is my problem:
At the moment I have 2 tables.
Users Table:
ID | Username | Password
1 | Micky | 123
2 | Mouse | 145
Questions Table:
Question ID| Question_Title | Question | Rating | Category ID | User ID |
1 | Meaning of Life? | Same as Title | 100 | 2 | 1 |
2 | Foo is love? | Same as Above | 95 | 4 | 2 |
Now I simply want to run a query which will find a match in the title and the find out which user ID corresponds to that question and then get the name of the user, as well as the Question Title, Question and Rating then print them out.
So far I have:
"SELECT Question_Title, Question, Rating FROM Questions WHERE Question_Title LIKE '%$Term%'";
This works as in it will get me the Question Title, Question and Rating from the table wherever it finds a match but how would I use JOIN so that it will also get me the Username from the Users table?
Also this is just early implementation I will in the future have a lot more tables that will require similar query so I need to understand how this works.
P.S: I know their are plenty of examples like this but I had trouble understanding them so if one of you kind souls could break it down and explain I would be grateful.
Try this
SELECT
u.username
q.Question_Title,
q.Question,
q.Rating
FROM Questions q
join Users u on u.id = q.userid
WHERE q.Question_Title LIKE '%$Term%'";
Select a.* from a join b on a.id=b.a_id join c on c.b_id = b.id
in your case something like this:
SELECT Question_Title, Question, Rating,user.* FROM Questions join User on user_id=id WHERE Question_Title LIKE '%$Term%'";

Kohana/PHP - Retrieving items based on user applied filter

My website is Q&A site like stackoverflow.com. When a user creates a question he have the ability to attach some tags to it. Later, when he need to find all questions which belongs to a category, he can use the filter box which accepts tag names. based on user entries i will just refresh the job list.
My table design is like below
Table: Questions
id | QuestionTitle |Other details.....|
1 | Why is earth round? |.............|
2 |How much is moon's diameter?|......|
Table: Tags
id | tagname
1 | planets
2 | earth
3 | moon
Table: AttachedTags
id | question_id | tag_id
1 | 1 |2
2 | 1 |1
3 | 2 |3
In the PHP/Controller i will get tag id's as user input's in the filter box.
What is the best method to fetch all those questions under a particular tag.
I am using PHP and Kohana 3.3
try joining your tables as shown, join both tables based on question id
select q.id,q.title
from questions q inner join attachedtags at on (q.id = at.question_id) where at.tag_id = ur-passed-tag-id

Clarification On MySQL Join Query

I am having some issues creating this JOIN query.
The table setup is as follows
| tags || tag_links || articles |
|________________||________________||________________|
| | | | | |
| id | | article_id | | id |
| tag_name | | tag_id | | |
There are 3 tables, and this is a many-to-many relationship.
The objective is to find all the tags associated with a given article
id.
The tags table contains all of the tags
The tag_links table contains the link between the articles and the
tags, where the tag_id is equal to the id in the tags table, and the
article_id is equal to the id in the article table
The articles table contains the id ( amongst other columns, but the
other columns are not important )
I am having a hard time because the article id is already provided. I don't think that this is even needed in the query, but I am at a loss right now. I am trying to grab all of the tag_id's that are associated with the article_id that I pass in, and then grab all of the tag_names from all of the tag_id's i just queried for.
Any help is greatly appreciated. Thanks!
This is a simple join you can use to get tag names for a given article id
select distinct t.* from tags t
join tag_links tl on(t.id = tl.tag_id)
where tl.article_id=#id <---- article id

Reorder/reset column unique id in mysql

I do not know a lot of mysql. I have two tables on same server:
A.artists
id | artist_name
--------------------
8 | XXXX |
1 | YYYY |
5 | ZZZZ |
A.albums
id | artist_id | album_name
-----------------------------
1 | 5 | Album 1
2 | 1 | Album 2
3 | 8 | Album 3
I want to reorder the artist_id column, accordingly, at the same time I want to change A.artists's id column from reordered artist_id id.
Is it possible such a thing? How can I do that? Thanks!
First, you need to understand that tables in SQL are unordered. So, you cannot specify an ordering for the table. You can specify an ordering for a query.
My guess is that you want to join the two tables to get the name with the albums:
select al.*, ar.name
from albums al join
artists ar
on al.artist_id = ar.id
order by ar.name
The way your question is phrased is that you want to re-assign ids. Normally, this would not be necessary, since the ids exist only to uniquely identify rows. If you have a good reason for reassigning ids, then modify your question or ask a new question, including the reason.

mysql select query problem

i have a form that has a multiple select drop down. a user can select more than one options in the select. the name of the select is array[]; using php I call implode(",",$array)
in mysql db, it stores the field as a text in this format "places"= "new york, toronto, london" when i want to display these fields i explode the commas.
I am trying to run a report to display the places. here is my select:
"select * from mytable where db.places .. userSelectedPlaces"
how can i check toronto in lists of "places" that user selected? note "places" in the db might be either just "toronto" or it might be comma separated lists of places like "ny, toronto, london, paris, etc".
If it is possible, you would be much better off using another table to hold the places that the user has selected. Call it SelectedPlaces with columns:
mytable_id - To join back to the table in your query
place - EG: "Toronto"
Then you can run a simple query to figure out if Toronto has been selected:
SELECT *
FROM mytable m
INNER JOIN SelectedPlaces sp ON sp.mytable_id = m.id
WHERE sp.place = 'Toronto'
If I understand you correctly, your database design is just wrong. Try reading about it more. Generally, in good design you should not have lists of values as one field in database and you should introduce new table for it.
But if you want to do it this way, you can use strcmp function.
If i understood correctly, this should work:
WHERE DB.PLACES LIKE '%TORONTO%'
but as other users said, its not a nice thing to have denormalized tables.
To directly answer your question, your query needs to look something like this
SELECT *
FROM mytable
WHERE places LIKE( '%toronto%' )
But, be aware, that LIKE() is slow.
To indirectly answer your question, your database schema is all wrong. That is not the right way to do a M:N (many-to-many) relationship.
Imagine instead you had this
mytable place mytable_place
+------------+ +----------+----------+ +------------+----------+
| mytable_id | | place_id | name | | mytable_id | place_id |
+------------+ +----------+----------+ +------------+----------+
| 1 | | 1 | new york | | 1 | 1 |
| 2 | | 2 | toronto | | 1 | 2 |
| 3 | | 3 | london | | 1 | 3 |
+------------+ +----------+----------+ | 2 | 2 |
| 3 | 1 |
| 3 | 3 |
+------------+----------+
The table mytable_places is what's called a lookup table (or, xref/cross-reference table, or correlation table). Its only job is to keep track of which mytable records have which place records, and vice versa.
From this example we can see that The 1st mytable record has all 3 places, the 2nd has only toronto, and the 3rd has new york and london.
This opens you up too all sorts of queries that would be difficult, expensive, or impossible with your current design.
Want to know how many mytable records have toronto? No problem
SELECT COUNT(*)
FROM mytable_place x
LEFT JOIN place p
ON p.place_id = x.place_id
WHERE p.name = 'toronto';
How about the number of mytable records per place, sorted?
SELECT p.name
, COUNT(*) as `count`
FROM mytable_place x
LEFT JOIN place p
ON p.place_id = x.place_id
GROUP BY p.place_id
ORDER BY `count` DESC, p.name ASC
And these are going to be much faster than any query using LIKE since they can use indexes on columns such as place.name.

Categories