I'm trying to delete a row from table subscription where there is two foreign Keys (id_user and id_journal). The information that I have is email from table user and nome from table journal. The deleted row needs to match user.email and journal.nome. I can't find a solution. How can I do it?
Table user:
id
name
email
password
Table journal:
id
name
Table Subscription:
id
id_user
id_journal
The last two queries that I tried:
DELETE FROM assinatura WHERE (
SELECT tbluser.id, journal.id
FROM tbluser, journal
WHERE email = '$email' AND nome = '$nome')
DELETE FROM assinatura
INNER JOIN tbluser on (tbluser.email = '$email')
INNER JOIN journal on (journal.nome = '$nome')
I've tried many others queries, but unsuccessful. I think it's important to say that I'm new at MySQL.
DELETE
FROM Subscription
WHERE id_user IN (
SELECT usr.id
FROM user AS usr
WHERE usr.email = INPUT_EMAIL
)
AND id_journal IN (
SELECT jrnl.id
FROM journal AS jrnl
WHERE jrnl.name = INPUT_NAME
)
On another topic ...
Try to avoid excess subscriptions for same user/journal combo by
CREATE TABLE subscription
(
id int NOT NULL AUTO_INCREMENT primary key,
id_user int not null,
id_journal int not null,
UNIQUE KEY `user_journal_intersect` (`id_user`,`id_journal`)
-- note Alan stated FK RI in place already
);
U can PK on composite instead, of course (ditching the id column), programmer pref
Related
I have a current users table. A distinct user is defined as when the email and phoneNumber together are unique. Currently the table looks like this:
And another table called giftee_info which has the foreign key on column userId to users.id:
The users table is going to be parsed out into 2 tables: users and user_metadata. Now a distinct user will be defined by the phoneNumber. So you can see in the data above, users with id's 4 and 5 are the same, and have to be merged.
The new users table will look like:
And the new user_metadata table will look like this:
Note how the 4th row has userId of 4, so users 4 and 5 have merged to one user.
And giftee_info will look like this:
See how the 3rd row in giftee_info contains userId 4, as the user with id 5 has been merged into one user.
The data I've provided is basic. In reality there are many rows, and a user with the same number may have 5 different email address (and so are currently treated as separate users in the current schema).
The part I'm having most trouble with is updating giftee_info. So any rows with userId's that have been merged down into one user need to be updated. How can I do this?
Since phonenumber can be NULL, I'm using externalid as the unique identifier below.
Start by creating the new users table from the distinct phone numbers in the old users table:
CREATE TABLE new_users (id INT PRIMARY KEY AUTO_INCREMENT, externalid VARCHAR(32), phonenumber VARCHAR(32))
SELECT DISTINCT NULL, externalid, phonenumber
FROM users
Then put all the emails into the user_metadata table, by joining the old and new users tables to get the emails along with the new user IDs.
CREATE TABLE user_metadata (id INT PRIMARY KEY AUTO_INCREMENT, userid INT, email VARCHAR(100), subscribe INT(1))
SELECT NULL, nu.id, u.email, 0
FROM new_users as nu
JOIN users AS u ON nu.externalid = u.externalid
Now you can update giftee_info by replacing the old user IDs with the new user IDs.
UPDATE giftee_info AS g
JOIN users as u ON g.userid = u.userid
JOIN new_users As nu ON nu.externalid = u.externalid
SET g.userid = nu.userid
Once this is all done you can rename the tables so new_users is now users.
currently I have three table: test, contact and staff
test
FirstName LastName
Contact
Contact_Id Contact_FirstName Contact_LastName
staff
Staff_ID Contact_Id
The Staff Id should be auto-increment, I need a script that go through all row in test table. If the FirstName and LastName Matches Contact_FirstName and Contact_LastName. Add Matched Contact_ID number to the Contact_Id thats in the Staff table.
INSERT INTO `staff` (`Contact_Id`)
SELECT c.`ContactId`
FROM `Contact` c
JOIN `Test` t ON c.`Contact_FirstName` = t.`FirstName` AND
c.`Contact_LastName` = t.`LastName`
First change the structure of Staff table by adding IDENTITY in CREATE statement if you want it to be auto-incremented.
CREATE TABLE Staff (StaffID INT IDENTITY, ContactID INT)
now try this to insert just contactID because IDENTITY allows you to skip that column, sql creates those IDs for you.
INSERT Staff SELECT Contact_ID FROM Contact c JOIN Test t ON c.Contact_FirstName=t.FirstName and c.Contact_LastName=t.LastName
this seems like it's checking contact names of Contact based on Contact names of Test.. but this should work if you pass name of person in place of t.FirstName and t.LastName
I've got 3 tables for a chat system:
conversation this table holds an id and timestamp
conversation_participant tells me which users are in the chat
conversation_message the messages send within this chat (also holds sender_id)
This setup works quite good for me but now I want to do a 'reverse' lookup. I know which users are going to start a new chat and I want to know if this specific group already has a conversation in the DB. Is there a way to find a row based on a dynamic set of foreign rows?
(preferable without pivot like tricks)
Or is my database design flawed and should I alter that?
CONVERSATION
id int auto_increment
start timestamp
CONVERSATION_PARTICIPANT
conversation_id int (foreign key to conversation)
participant_id int (foreign key to users table)
CONVERSATION_MESSAGE
id int auto_increment
conversation_id int (foreign key to conversation)
author_id int
time timestamp
message text
This assumes you:
have a list of comma delimited participant_id's -> $list
know the number of participants -> $qty
use one of the participants in the WHERE clause -> $participant
replace those pseudo-variable with real values
You can see the code here: http://sqlfiddle.com/#!2/e90f2/11
Code:
SELECT conversation_participant.conversation_id AS conversation_id
, SUM(IF(members.participant_id IN ($list),1,0)) AS member_count
, COUNT(*) AS total
FROM conversation_participant
JOIN conversation_participant AS members
ON members.conversation_id = conversation_participant.conversation_id
WHERE conversation_participant.participant_id = $participant
GROUP BY conversation_id
HAVING member_count = total
AND member_count = $qty;
FYI: The purpose of the WHERE clause is to limit the number of potential conversations.
I just want to update automatically a column of 2 tables linked with foreign keys.
To more, these columns have to contain not just one value, but a list of values.
Here is my example :
Table Name : members
Member name : Demo User
Assigned Tasks : <List of tasks assigned to "Demo User">
Table Name : tasks
Task Name : Modeling
Assigned To : <List of users assigned to "Modeling">
In each table, I want to be able to insert value in the column, and the other table is automatically updated.
Example :
Table Name : members
Member name : Demo User
Assigned Tasks : Modeling,Mapping
Table Name : tasks
Task Name : Modeling
Assigned To : AUTOMATIC UPDATE ->Demo User
Task Name : Mapping
Assigned To : AUTOMATIC UPDATE ->Demo User
I tried with foreign keys (using innoDB), but I just succeed to insert one value in the column, and the other table was not updated automatically...
Thank you for your help !
Never, ever store delimited values in a database. Normalize your data by creating a many-to-many table (in your case let's call it assigned_tasks) instead. It will pay off big time in a long run by enabling you to normally maintain and query your data.
That being said your schema might look like
CREATE TABLE members
(
member_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
member_name VARCHAR(32)
);
CREATE TABLE tasks
(
task_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
task_name VARCHAR(32)
);
CREATE TABLE assigned_tasks
(
member_id int,
task_id int,
PRIMARY KEY (member_id, task_id),
FOREIGN KEY (member_id) REFERENCES members (member_id),
FOREIGN KEY (task_id) REFERENCES tasks (task_id)
);
Now if you need a representation with a delimited list of tasks per user you can use GROUP_CONCAT() and GROUP BY
SELECT m.member_id, m.member_name, GROUP_CONCAT(t.task_name) tasks
FROM assigned_tasks a JOIN members m
ON a.member_id = m.member_id JOIN tasks t
ON a.task_id = t.task_id
GROUP BY m.member_id, m.member_name
Output:
| MEMBER_ID | MEMBER_NAME | TASKS |
|-----------|-------------|------------------|
| 1 | Demo User | Modeling,Mapping |
Here is SQLFiddle demo
I'm currently trying to make a small web service, just for fun and learning. (I recently started to learn programming practically.)
The service is like twitter. users follow their friends and get statuses of them.
I have a question about relational db.
There are 3 tables, which are 'user','friendship' and 'status'.
here are codes to describe what these tables look like.
create table user (
id int unsigned auto_increment primary key,
username varchar(16) not null,
password varchar(255) not null,
created datetime default null
);
create table friendship (
id int unsigned auto_increment primary key,
userid int not null,
friend int not null,
created datetime default null
);
create table status (
id int unsigned auto_increment primary key,
userid int not null,
current_status int not null,
created datetime default null
);
'user.id' is equal to 'friendship.userid' and 'status.userid'.
・The situation is;
1, a user logged in, and will get his friends' status numbers.
2, php got the user's id and find his friends's userid, username, status and created (of status).
I tried some sql sentences but not working.
Could any super sql writer show me correct sql ?
Cheers!
Edited 1;
I tried sql like this;
select userid, username, current_status, created
from status
join users u1
on u1.id = status.userid
join friendship
on friendship.friend = u1.id
join user u2
on u2.id =friendship.userid
where u2.id = "the user's id from php";
and mysql throw this "#1146 - Table 'Application.user' doesn't exist."
Your first join statement has "users" while your table name is "user." This is a common newbie error. You should pick standard and follow it. Most DBs that I see use the singular form, so there is no confusion whether your tables names are "friends" or "friend."
Not to worry though, I think practically everyone makes this mistake when starting out. There might be other errors, but this one pops out immediately.
Try fixing that and letting us know how it goes.
Oh, and in table selects declare which table I am selecting from: i.e. SELECT from user.userid, …
Something like this should work:
select u1.userid, username, current_status, created
from status
inner join [user] u1 on u1.id = status.userid
inner join friendship on friendship.friend = u1.id
inner join [user] u2 on u2.id = friendship.userid
where u2.id = #User2Id
Like was mentioned in the comments: Table 'Application.user' doesn't exist
In SQL Server user is a reserved word so we add the square braces around it. (see code). Or you change the table name to be something else (IE Client, TwitterUser, etc...)