There are 4 Tables:
Users: id,name
Albums: id,user_id
Pictures: id,picture_name,album_id
Tags: picture_id , user_id
I need to write 2 commands:
- a command which deletes a picture by its name -
which means, removing it from the "Tags" table and from the "Pictures" table.
- a command which adds a tag to a picture of a User.
I have tried so far those two commands (which don't seem to work):
Deleting from the tags table:
DELETE FROM Tags
JOIN Albums
ON Users.id=Albums.user_id
JOIN PICTURES
ON Pictures.album_id = Albums.id
WHERE Pictures.name LIKE "pic_name.png" ;
Deleting from the pictures table:
DELETE FROM Pictures
WHERE Pictures.name LIKE "pic_name.png" ;
Adding a tag of " user1 " on picture "pic_name2.png" to the Tags table:
INSERT INTO Tags (user_id,picture_id) SELECT Users.id, Pictures.id FROM Albums JOIN Users ON Users.id=Albums.user_id JOIN PICTURES ON Pictures.album_id = Albums.id WHERE Users.name LIKE "user1" and Pictures.name= "pic_name2.png";
please help me write those queries correctly ...
try like below
delete from Tags
where user_id in
( select user_id from Albums
JOIN PICTURES
ON PICTURES.album_id = Albums.id
WHERE Pictures.name LIKE '%pic_name.png%'
)
2nd query
DELETE FROM Pictures
WHERE Pictures.name LIKE '%pic_name.png%'
and 3rd query only need change where
WHERE Users.name ='user1' and Pictures.name= 'pic_name2.png'
You don't need to join any tables to delete the rows:
delete from tags
where picture_id = (
select id from pictures
where picture_name = 'pic_name.png'
);
delete from pictures
where picture_name = 'pic_name.png';
The tables users and pictures cannot and do not need to be joined.
You can insert a new row like this:
insert into tags (user_id, picture_id) values
(
(select id from users where name = 'user1'),
(select id from pictures where picture_name = 'pic_name2.png')
);
As you can see I changed all like to = because this is what you need in this case.
See more here
Related
I am pretty new to SQL. I am trying to update one table with the data from another.
Table1: albums
album_id
user_id - correct value
Table2: images
image_id
album_id
user_id - wrong value
I need to update
images.user_id with data from albums.user_id where albums.album_id = images.album_id
You can use an update/join:
update images i join
albums a
using (album_id)
set i.user_id = a.user_id;
It's a simple table that looks like this:
id TEXT,
name TEXT,
FOREIGN KEY(id) REFERENCES users(id) ON DELETE CASCADE,
PRIMARY KEY(id, name)
What I want is to be able to get a set of rows with counts for all names in that table. Basically how many times each name is present in the table.
This is my code so far and it works:
var names = ['upload_files', 'create_users', 'remove_users', 'edit_tags'];
var query = 'SELECT COUNT(p.id) AS count FROM perms p JOIN users u ON p.id = u.id WHERE p.name = ?',
for(let name of names){
this.db.prepare(query).all([name]).map(value => data[name] = value.count);
}
It produces something like this:
upload_files: 5,
create_users: 2,
remove_users: 2,
edit_tags: 5,
Assuming there are 5 rows with upload_files, 2 rows with remove_users and so on...
But it's very slow when I have 50K records, each query takes 2 seconds.
Can it be combined in a single query? that way I can reduce the time to 2 seconds for all names
Filter the names using IN and group by the name.
SELECT p.name,
count(p.id) count
FROM perms p
WHERE p.name IN ('upload_files',
'create_users',
'remove_users',
'edit_tags')
GROUP BY p.name;
And consider to try if an index on name speeds things up.
I have a table that contains all of the posts. I also have a table where a row is added when a user likes a post with foreign keys user_id and post_id.
I want to retrieve a list of ALL of the posts and whether or not a specific user has liked that post. Using an outer join I end up getting some posts twice. Once for user 1 and once for user 2. If I use a WHERE to filter for likes.user_id = 1 AND likes.user_id is NULL I don't get the posts that are only liked by other users.
Ideally I would do this with a single query. SQL isn't my strength, so I'm not even really sure if a sub query is needed or if a join is sufficient.
Apologies for being this vague but I think this is a common enough query that it should make some sense.
EDIT: I have created a DB Fiddle with the two queries that I mentioned. https://www.db-fiddle.com/f/oFM2zWsR9WFKTPJA16U1Tz/4
UPDATE: Figured it out last night. This is what I ended up with:
SELECT
posts.id AS post_id,
posts.title AS post_title,
CASE
WHEN EXISTS (
SELECT *
FROM likes
WHERE posts.id = likes.post_id
AND likes.user_id = 1
) THEN TRUE
ELSE FALSE END
AS liked
FROM posts;
Although I was able to resolve it, thanks to #wildplasser for his answer as well.
Data (I needed to change it a bit, because one should not assign to serials):
CREATE TABLE posts (
id serial,
title varchar
);
CREATE TABLE users (
id serial,
name varchar
);
CREATE TABLE likes (
id serial,
user_id int,
post_id int
);
INSERT INTO posts (title) VALUES ('First Post');
INSERT INTO posts (title) VALUES ('Second Post');
INSERT INTO posts (title) VALUES ('Third Post');
INSERT INTO users (name) VALUES ('Obama');
INSERT INTO users (name) VALUES ('Trump');
INSERT INTO likes (user_id, post_id) VALUES (1, 1);
INSERT INTO likes (user_id, post_id) VALUES (2, 1);
INSERT INTO likes (user_id, post_id) VALUES (2, 2);
-- I want to retrieve a list of ALL of the posts and whether or not a specific user has liked that post
SELECT id, title
, EXISTS(
--EXISTS() yields a boolean value
SELECT *
FROM likes lk
JOIN users u ON u.id = lk.user_id AND lk.post_id=p.id
WHERE u.name ='Obama'
) AS liked_by_Obama
FROM posts p
;
Results:
id | title | liked_by_obama
----+-------------+----------------
1 | First Post | t
2 | Second Post | f
3 | Third Post | f
(3 rows)
As far as I understand, you have two tables such as post table which includes all post from different users and a like table with user.id and post id. if you want to retreive only posts then
select * from posts
if you need user information as well, which is present in user table then you can do below.
select user.user_name, post.postdata from user,post where post.userid=user.userid
in above query, user_name is a column name in user table and postdata is a column in post table.
I have the following structure:
CREATE TABLE stories
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
dir TEXT,
alias TEXT,
title TEXT
);
CREATE TABLE tags
(
story_id INTEGER,
name TEXT
);
Now I want to select all stories that have (at least) given N tags, and do not have another N tags.
Example: All stories with "fantasy" and "nature", but without "dragons"
Here's a query I tried (for now just the "whitelist" part, but it's extremely slow - so I'm sure I'm doing it wrong.
SELECT s.*
FROM stories s
WHERE
(SELECT COUNT(*)
FROM tags t
WHERE
t.story_id = s.id
AND t.name IN ('fantasy', 'nature')
) = 2
If I add "LIMIT 10" at the end, it works (but very slowly).
No idea how to include the blacklist criteria into the query, though.
Ideas?
I have about 20.000 stories and 75.000 tag entries.
This can be easily done with subqueries:
SELECT ...
FROM stories
WHERE id IN (SELECT story_id FROM tags WHERE name = 'fantasy')
AND id IN (SELECT story_id FROM tags WHERE name = 'nature' )
AND id NOT IN (SELECT story_id FROM tags WHERE name = 'dragons');
Alternatively, use a compound query to combine the tag filters:
SELECT ...
FROM stories
WHERE id IN (SELECT story_id FROM tags WHERE name = 'fantasy'
INTERSECT
SELECT story_id FROM tags WHERE name = 'nature'
EXCEPT
SELECT story_id FROM tags WHERE name = 'dragons');
Which one is faster depends on the number of tags you're checking, and on the selectivity of your filters; you'll have to try.
Both queries are efficient if there is an index on the tags.name column.
I have two tables: photos (id,path) and tags(id,name).
Tables are in many-to-many relationship, so I've got a third table:
photos_tags(photos_id, tags_id).
Now, how can I connect a photo of specified path with tag of specified name?
I'd like to do something like this:
INSERT INTO photos_tags
SELECT photos.id, tags.id FROM photos, tags
WHERE photos.path = '/some/path' AND tags.name = 'tag';
insert into photos_tags
(photos_id, tags_id)
select id,
(
select id
from Tags
where name = 'tag'
)
from photos
where path = '/some/path'