How to use search query with join tables? - php

I have two tables in a database. The first table is "tb_ctsreport" with fields "qr_id, idNum, date, time" and the other one is "tb_usersreg" with many fields which includes idNum, firstName, lastName, age and address. I have displayed my table using this query:
$query = "SELECT * FROM tb_ctsreport LEFT JOIN tb_usersreg ON tb_ctsreport.idNum=tb_usersreg.idNum";
This gives me a resulting table of qr_id, idNum, Name(concatenated firstName and lastName), date, time.
Then I wanted to create a search query from this table that I have created, however, I am lost and I don't know how will I include the values firstName and lastName when searching because it is placed in another table. This is my working query except for an undefined index for displaying the name since I don't know how.
$query = "SELECT * FROM tb_ctsreport WHERE CONCAT(qr_id, idNum, time, date) LIKE '%".$searchBox."%'";
I have also tried this sql query but only gives me an error.
$query = "SELECT * FROM tb_ctsreport WHERE CONCAT(qr_id, idNum, time, date) LIKE '%".$searchBox."%'
UNION
SELECT * FROM tb_usersreg WHERE CONCAT(lastName, firstName) LIKE '%".$searchBox."%'";
Please help me. I am just new to php. Thank you!

You can use a WHERE clause after the JOINs clauses. So you can write your SQL query as:
SELECT *
FROM tb_ctsreport
LEFT JOIN tb_usersreg ON tb_ctsreport.idNum = tb_usersreg.idNum
WHERE
CONCAT(
tb_ctsreport.qr_id,
tb_ctsreport.idNum,
tb_ctsreport.time,
tb_ctsreport.date,
tb_usersreg.lastName,
tb_usersreg.firstName
) LIKE :searchBox
In the above query :searchBox is your query parameter.
Care when you concatenate user input with your SQL query, this introduces a huge security vulnerability called SQL Injection. You shuld prefer to use parameterized query to avoid this issue.
When you are referencing multiple tables in an SQL query I advise you to always use the fully qualified name for the columns in order to avoid any ambiguity.

Related

SELECT statements have different number of columns

I am making a small php website in which you can follow others and then see their post.
I have three tables-
1.Posts, which has post_id and author_id
2.follow, which has following and follower
3.users, which has id, username, and all other stuff. I try the following in sql-
SELECT * FROM posts,follow,users WHERE posts.author_id=users.id AND users.id=follow.following AND follow.follower='$id' UNION SELECT * FROM posts,users WHERE posts.author_id=users.id AND users.id='$id'
Where $id is the id of the user logged in.
It displays the following error-
#1222 - The used SELECT statements have a different number of columns
I have searched for hours but I cannot find the answers to match with my query.
I will really appreciate an answer with a better version of the above code.
Thanks in advance.
Perhaps a JOIN would serve you better ... something like this:
SELECT * FROM posts
JOIN users on posts.author_id=users.id
JOIN followers on users.id=follow.following
WHERE follow.follower='$id'
When you union two queries together, the columns on both must match.
You select from posts,follow,users on the first query and posts,users on the second.
this won't work.
From the mysql manual:
The column names from the first SELECT statement are used as the column names for the results returned. Selected columns listed in corresponding positions of each SELECT statement should have the same data type

MYSQL/PHP - Select all columns from table records distincting by one column

I'm a bit confused about DISTINCT keyword. Let's guess that this query will get all the records distincting the columns set in the query:
$query = "SELECT DISTINCT name FROM people";
Now, that query is fetching all the records distincting column "name" and at the same time only fetching "name" column. How I'm supposed to ONLY distinct one column and at the same time get all the desired columns?
This would be the scheme:
NEEDED COLUMNS
name
surname
age
DISTINCTING COLUMNS
name
What would be the correct sintaxis for that query? Thanks in advance.
If you want one row per name, then a normal method is an aggregation query:
select name, max(surname) as surname, max(age) as age
from t
group by name;
MySQL supports an extension of the group by, which allows you to write a query such as:
select t.*
from t
group by name;
I strongly recommend that you do not use this. It is non-standard and the values come from indeterminate matching rows. There is not even a guarantee that they come from the same row (although they typically do in practice).
Often, you want something like that biggest age. If so, you handle this differently:
select t.*
from t
where t.age = (select max(t2.age) from t t2 where t2.name = t.name);
Note: This doesn't use group by. And, it will return duplicates if there are multiple rows with the same age.
Another method uses variables -- another MySQL-specific feature. But, if you are still learning about select, you should probably wait to learn about variables.

How to form the proper query

I am trying to form a query for MySQL where it gets all the info from multiple tables but only displays the ones where the "activity" = "Other". Right now it is displaying everyones info and I don't know the proper way to format the WHERE part of the query. I want it to access the jobSearch table, read the activity and only return the ones where the activity is "Other"
$query_student = " SELECT *
FROM student
JOIN major
ON student.studentID=major.studentID
JOIN jobSearch
ON major.studentID=jobSearch.studentID
WHERE jobSearch.activity == Other";
You SQL syntax is wrong, it should be:
SELECT * FROM table_name WHERE column = value
In your case:
SELECT * FROM student ... WHERE jobSearch.activity = 'Other'
For reference, check this good tutorial about SQL syntax: http://www.tutorialspoint.com/sql/sql-where-clause.htm
Your SQL syntax is OK is not wrong
SELECT *
FROM student
JOIN major ON student.studentID=major.studentID
JOIN jobSearch ON major.studentID=jobSearch.studentID
WHERE jobSearch.activity = 'Other';
If jobsearch.activity field is a varchar use single quotes around the word Other and use only one "=".
Also I recommend using alias and not using "Select *", you might run into a problem because you have the same field name in different tables, try to use something like this.
SELECT st.*, mj.field1, mj.field2, js.activity, js.field2
FROM student st
JOIN major mj ON st.studentID=mj.studentID
JOIN jobSearch js ON mj.studentID=js.studentID
WHERE js.activity = 'Other';

PHP SQL Query - Select All Associated w/ Specific Value?

I could use some assistance with an sql query. I have a small 3 column table, id, ip, and birthday. id auto increments.
I'm trying to select all birthdays that are associated with a specific ip, but I'm not sure if the SQL statement I wrote is correct. If someone could check this for me it would be appreciated.
$query = "SELECT birthday, COUNT(ip) FROM $table Group By ip HAVING ( COUNT(ip) > 1) WHERE ip=$ip";
To get all the birthdays with a specific IP you'd simply query:
SELECT birthday FROM table WHERE ip="desired value here"
If you're trying to count that information, then you could use:
SELECT ip, count(*) as `Total` FROM table WHERE id="desired value here" GROUP BY ip
Select birthday from $table where ip='<ip goes here>'
Be sure to properly escape your inputs. PDO or MySQLi prepared statements are advisable.

SELECT COUNT(DISTINCT name), id, adress from users

With PHP I'm trying to run a SQL query and select normal columns as well as COUNT.
$sql_str = "select COUNT(DISTINCT name), id, adress from users";
$src = mysql_query($sql_str);
while( $dsatz = mysql_fetch_assoc($src) ){
echo $dsatz['name'] . "<br>";
}
The problem is that when I have "COUNT(DISTINCT name)," in my query, it will only return the first entry. When I remove it, it will return all matching entries from the db.
I could separate it and do 2 queries, but I'm trying to avoid this due to performance concerns.
What do I make wrong?
thx, Mexx
The ability to mix normal columns and aggregate functions is a (mis)feature of MySQL.
You can even read why it's so dangerous on MySQL's documentation:
https://dev.mysql.com/doc/refman/5.6/en/group-by-extensions.html
But if you really want to mix normal rows and a summary in a single query, you can always use the UNION statement:
SELECT COUNT(DISTINCT name), null, null FROM users GROUP BY name --summary row
UNION
SELECT name, id, address FROM users --normal rows
COUNT() is an aggregate function, it aggregates against the results of the rest of your query. If you want to count all distinct names, and not just the distinct names associated with the id and address that you are selecting, then yes, you will have to run two queries. That's just how SQL works.
Note that you should also have a group by clause when aggregating. I think the fact that MySQL doesn't require it is horrible, and it encourages really bad habits.
From what I understand, you want to get :
one line per user, to get each name/id/address
one line for several users at the same time, to get the number of users who have the same name.
This is not quite possible, I'd say.
A solution would be, like you said, two queries...
... Or, in your case, you could do the count on the PHP side, I suppose.
ie, not count in the query, but use an additionnal loop in your PHP code.
When you have a count() as part of the field list you should group the rest of the fields. In your case that would be
select count(distinct name), id, adress from users group by id, adress
select count(distinct name), id, adress
from users
group by id, adress
I'm assuming you want to get all your users and the total count in the same query.
Try
select name, id, address, count(id) as total_number
from users
group by name, id, address;

Categories