I'm making a notifications widget on my website and I'm trying to make it so that if a notification is marked as read, that notification ID will be inserted into another table (table 'b') along with their username so that it is marked as read. Now the problem that I run into is when displaying all notifications (whether they're read or unread) I don't know how to indicate if the notification exists in the secondary table
The currently SQL query is as follows:
$qry = "SELECT * FROM notifications WHERE (notif_recipient = '$user') ORDER BY notif_date DESC";
What I'd like to do is make the query much more complex in order to indicate if a notification exists in another table, so something along the lines of:
$qry = "SELECT notif_id,notif_message,(CASE SELECT notif_is_read AS '1' WHERE notif_id.notifications = notif_id.notifications_read ELSE SELECT notif_is_read AS '0') FROM notifications WHERE (notif_recipient = '$user') ORDER BY notif_date DESC";
Is something like this possible or is it as preposterous as my lack of ability for writing SQL queries
As Marc B had suggested, I decided to use LEFT JOIN in order to identify which messages currently exist in the secondary table, with my query looking as such:
$qrytest = "SELECT notifications.notif_id,notifications.notif_message,notifications.notif_flag,notifications.notif_poster,notifications.notif_date,notifications_read.notif_read_count FROM notifications LEFT JOIN notifications_read ON notifications.notif_id=notifications_read.notif_id WHERE ((notif_recipient = 'all') OR (notif_recipient = '$id')) ORDER BY notif_date DESC,notif_flag DESC";
This in turn will return the results of my primary table (notifications) and if the same notification id exists in my secondary table, I decided to echo out that table's ID count, if the entry does not exist it will simply return as null
$exists = $row['notif_read_count'];
if ($exists !== ''){
// When NOT returning as null do something
} else {
// When exist returns as null do something
}
Related
I am creating a Log in and I have separate tables for Users A and Users B.
What I want to do is check first in first table if the Users that trying to Login is in the Table A,
if YES, it will not go to the Table B to check the Login credentials, if NOT, go to Table B and check the Login credentials.
Table A
SELECT * FROM tableA WHERE userId='$userId' AND password='$password'
Table B
SELECT * FROM tableB WHERE accountNumber='$accountNumber' AND password='$password'
Note: The 2 Tables has different Field Name userId and accountNumber.
I presume you are fetching the values of username and password from client side so I will tell you only what you asked for.
$getUserBasic1=$db->prepare('SELECT * FROM tableA WHERE userId="$userId" AND password="$password"');
$getUserBasic1->execute();
$user= $getUserBasic1->fetchAll();
if(count($user)>0)
{
//if yes do what you want here
}
else
{
$getUserBasic2=$db2->prepare('SELECT * FROM tableB WHERE accountNumber="$accountNumber" AND password="$password"');
$getUserBasic2->execute();
$user2= $getUserBasic2->fetchAll();
//write your code here
}
You could use an INNER JOIN and select both table results taking Table A's result first if it exists, else take Table B's result.
Assuming both tables have some sort of reference like the User ID you can use something like this:
SELECT tbla.*, tblb.* FROM tableA tbla
INNER JOIN tableB tblb ON tbla.userId = tblb.userId
WHERE userId='$userId' OR accountNumber='$accountNumber' AND password='$password'
ORDER BY userId ASC
LIMIT 1
The query above uses the cross-reference (userId in this case) and joins both tables together before querying the results. It orders the results by Table A before Table B but limits the result to 1 bringing either Table A or Table B out depending which is null.
Try combining the tables, some thing like:
SELECT * FROM tableA, tableB WHERE tableA.userId='$userId' AND tableA.password='$password' OR tableB.accountNumber='$accountNumber' AND tableB.password='$password'
I have not checked, so may not work, but see if this gets what you are looking for!
Something like this:
$sql = "SQL QUERY FOR TABLEA";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// checking if result in TABLE A
}
else{
//search in TABLE B by updating your sql value.
}
I hope that you want to check for the registered user, the best way to do that is to keep one table and just search there itself keeping the userID as the primary key.
I'm trying to change my user's news feed to only show posts from friends, instead of from all users on the site. I managed to do so doing something like this:
function friend_posts(){
global $session_user_id;
if(friends_exist($session_user_id) === true){
$friends = mysql_query("SELECT * FROM `friendship` WHERE `user_id` = $session_user_id AND `pending` = 0");
while($friend = mysql_fetch_array($friends)){
$friendID = $friend['friend_id'];
$posts = mysql_query("SELECT * FROM `posts` WHERE `userid` = $friendID ORDER BY `timestamp` DESC");
while($post = mysql_fetch_array($posts)){
$friendData = user_data($post['userid'],'username','first_name','last_name');
echo $friendData['username'].": ".$post['status']."<br>";
}
}
} else {
echo "Nothing to display. Try adding some friends!";
}
}
However, this isn't that convenient. For example, if I want to paginate, I don't know how I'd even start to do that using something like this. Also if multiple users post, how would I sort them by 'timestamp' descending?
I'm guessing the only route I can take is accessing columns from multiple tables somehow, then sorting by the timestamp, which is stored in the posts table. The friendship table just has id, user_id, friend_id and pending.
How would I go about doing that? Is there an easier way to do what I'm trying to do?
I'm very new to SQL. I don't know too much other than inserting/deleting/updating.
You could use a single statement like this:
SELECT * FROM posts WHERE userid in
(SELECT friend_id FROM friendship WHERE user_id = $session_user_id AND pending = 0)
ORDER BY `timestamp` DESC
This way you get only the posts of the friends of the current user. If you also need data from the friendship table then use a join.
I have create a database Mysql and I am using in php. I want for each user to be checked if there is data.
I have three tables. In the table User has a unique value called ID_u and isn't auto_increment, the table Application has a unique value called ID(auto_increment) and table InformationUser has a unique value called ID(auto_increment). The tables Users and InformationUser joins with table Application.
ID_u = a user with id_u-> 1234
I'am try this:
if( ID_u exists data){
location1.php ->data
}else{
location2.php -> input information
}
I would be thankful for any help!!
I'm not sure I understand the structure of your database, but you may take a look at this:
$query = "
SELECT * FROM users u
LEFT JOIN application a
ON u.ID_u = a.ID_u
LEFT JOIN informationuser i
ON a.ID = i.ID
//Here you can specify 'WHERE u.ID_u IN (1,2,3,4)'
GROUP BY i.ID
" ;
$users = array() ; //Create storage for users. Use their ID as indeces
$result = $mysqli->query($query) ;
if ($result && $result->num_rows >= 1){
while ($row = $result->fetch_assoc()){
if (!isset($users[$row['ID_u'])){
$users[$row['ID_u']] = array() ; //Create array for a new user
}
$users[$row['ID_u']][] = array( //Fill array in with data and add it to user.
"email" => $row["email"],
"phone" => $row["phone"]
) ;
}
}
Afterwards, let's check if data exists for a user with ID = 3 (if 3 is an int):
if (!empty($users[3])){
echo "Yeah, data exists for user with ID 3" ;
}
First of all, if the user can only have one set of phone and email, it's better to save that data in the user table so that is has the following structure:
Users
ID_u
name
surename
email
phone
If you are set to keep the structure you have, my first tip is to take away the auto-increment on the table Application. That table is just meant to save the correlation between Users and InformationUser. Furthermore, the code you're looking for would be something like:
$sql = "SELECT * FROM Application WHERE ID_u = '1234'";
$result = mysql_query($sql) or die("Woops!");
if ($data = mysql_fetch_array($result)) {
include("location1.php");
}
else {
include("location2.php");
}
So you have users and you have applications. On each application there might be a different e-mail and name behind it. So you need to join and see if something exists. Something of this style
select count(*)
from Application
join InformationUser on (InformationUser.ID = Application.ID)
where
Application.ID_U = ?
The above gives you a count = 0 if both does not exist. If you want to know if both does not exists you can use an outer join.
I am building a mysql based chat application.
My database schema has the following tables,
Users Messages
================= =================
id id
screen_name message
from
to
timestamp
The from and to fields on the messages table contain the id's of the users that sent and received each message.
I am trying to display all messages between a user ($id) and one of their friends ($friend). My query is the following:
$query = "SELECT messages.* , users.screen_name FROM users CROSS JOIN messages ";
$query .= "ON ( messages.to = $id AND messages.from = $friend ) ";
$query .= "OR ( messages.to = $friend AND messages.from = $id )";
The problem is that every message is twice in the result table.
I tried using DISTINCT but it either doesn't work in this scenario or I used it wrong.
What should my query be in order to have each message between the two users only once?
Something like this should do the trick:
SELECT
messages.*,
users_from.screen_name AS from_screen_name,
users_to.screen_name AS to_screen_name
FROM
messages
JOIN users AS users_from ON messages.from = users_from.id
JOIN users AS users_to ON messages.to = users_to.id
WHERE
(messages.to = $id AND messages.from = $friend)
OR ( messages.to = $friend AND messages.from = $id)
What this does is joing the "users" table twice, once on the "to" column and the second time on the "from" column.
#Travesty3 has already suggested that the DISTINCT keyword will only exclude duplicate rows where all fields are equal to another row. Therefore, the DISTINCT keyword is not the way to go here.
What you can do, however, is to simply GROUP BY messages.id in order to get only one row per message ID (there is no guarantee, however, as to which of the two rows will be excluded).
I have the following 3 tables in the database.
Programs_Table
Program_ID (Primary Key)
Start_Date
End_Date
IsCompleted
IsGoalsMet
Program_type_ID
Programs_Type_Table(different types of programs, supports a dropdown list in the form)
Program_type_ID (Primary Key)
Program_name
Program_description
Client_Program_Table
Client_ID (primary key)
Program_ID (primary key)
What is the best way to find out how many clients are in a specific program (program type)?
Would the following SQL statement be the best way, or even plausible?
SELECT Client_ID FROM Client_Program_Table
INNER JOIN Programs_Table
ON Client_Program_Table.Program_ID = Programs_Table.Program_ID
WHERE Programs_Table.Program_type_ID = "x"
where "x" is the Program_type_ID of the specific program we're interested in.
OR is the following a better way?
$result = mysql_query("SELECT Program_ID FROM Programs_Table
WHERE Program_type_ID = 'x'");
$row = mysql_fetch_assoc($result);
$ProgramID = $row['Program_ID'];
$result = mysql_query("SELECT * FROM Client_Program_Table
WHERE Program_ID = '$ProgramID'");
mysql_num_rows($result) // returns how many rows of clients we pulled.
Thank you in advance, please excuse my inexperience and any mistakes that I've made.
Here is how you can do it:
<?php
// always initialize a variable
$number_of_clients = 0;
// escape the string which will go in an SQL query
// to protect yourself from SQL injection
$program_type_id = mysql_real_escape_string('x');
// build a query, which will count how many clients
// belong to that program and put the value on the temporary colum "num_clients"
$query = "SELECT COUNT(*) `num_clients` FROM `Client_Program_Table` `cpt`
INNER JOIN `Programs_Table` `pt`
ON `cpt`.`Program_ID` = `pt`.`Program_ID`
AND `pt`.`Program_type_ID` = '$program_type_id'";
// execute the query
$result = mysql_query($query);
// check if the query executed correctly
// and returned at least a record
if(is_resource($result) && mysql_num_rows($result) > 0){
// turn the query result into an associative array
$row = mysql_fetch_assoc($result);
// get the value of the "num_clients" temporary created column
// and typecast it to an intiger so you can always be safe to use it later on
$number_of_clients = (int) $row['num_clients'];
} else{
// query did not return a record, so we have no clients on that program
$number_of_clients = 0;
}
?>
If you want to know how many clients are involved in a program, you'd rather want to use COUNT( * ). MySQL (with MyISAM) and SQL Server have a fast way to retrieve the total number of lines. Using a SELECT(*), then mysql_num_rows leads to unnecessary memory ressources and computing time. To me, this is the fastest, though not the "cleanest" way to write the query you want:
SELECT
COUNT(*)
FROM
Client_Program_Table
WHERE
Program_ID IN
(
SELECT
Program_ID
FROM
Programs_Table
WHERE
Program_type_ID = 'azerty'
)
Why is that?
Using JOIN make queries more readable, but subqueries often prove to be computed faster.
This returns a count of the clients in a specific program type (x):
SELECT COUNT(cpt.Client_ID), cpt.Program_ID
FROM Client_Program_Table cpt
INNER JOIN Programs_Table pt ON cpt.Program_ID=pt.Program_ID
WHERE pt.Program_type_ID = "x"
GROUP BY cpt.Program_ID