Creating a connection between to tables in many-to-many relationship - sql

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'

Related

Postgres SQL INNER JOIN AND ARRAY_AGG

I have three simple tables:
Category which stores my list of different types of categoriesCategory Table
Items, which stores my items:
JunctionTable table, as a connection between category and items - relation N:M
item_list_category junction table
So my problem is, I would like to create select which will select data from all mentioned tables. First I tried this:
SELECT item_list_id, ARRAY_AGG(category_id) AS array_category
FROM item_list_category
WHERE item_list_id = 1
GROUP BY item_list_id;
With this result:
Attempt 1
Then I wanted to Join tables:
SELECT item_list_id, ARRAY_AGG(category_id) AS array_category
FROM item_list_category
WHERE item_list_id = 1
GROUP BY item_list_id;
This is result, but this is not obviously what I need.Attempt 2
I expected for instance: {"Dětské", "Misteriozní"} etc.

PostgreSQL select from 3 many-to-many tables

I'm using PostgreSQL, and I've got the following tables:
Category
Service
Report
All of them have many to many relationships to each other, so I've got the following tables for relationships between them:
link_category_service
link_category_report
link_service_report
I got stuck with the SQL query that allows getting all the categories-reports ids for the particular service with some id (for service with id 4, for instance):
category_id | report_id
You have a direct link between category and report - you can query the mapping table, and filter according to the link tables with the service table:
SELECT *
FROM link_category_report
WHERE category_id IN (SELECT category_id
FROM link_category_service
WHERE service_id = 4) AND
report_id IN (SELECT report_id
FROM link_report_service
WHERE service_id = 4)

Delete from a SQL Table using a couple JOINs

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

Select by multiple tags (whitelist and blacklist)

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.

Bulk update children table records set on master table records

I am using SQL Server 2008 R2. I have imported 2 tables from excel and I want to link them together. I looks like this:
Tables imported from Excel
brand (nvarchar(20) name)
models (nvarchar(20) parent, nvarchar(50 name))
Tables after my amends
brand (int ident id, nvarchar(20) name, tinyint status)
models (int ident id, int parent_id,
nvarchar(20) parent, nvarchar(50) name, tinyint status)
As you can see I'd like to link table models using parent_id to table brand using id.
Select is ok, I have done that.
What I need is create bulk update which would put brand id into model parent_id.
Conditions are:
set models.parent_id = brand.id where brand.name = model.parent
I hope it is clear. Basically I want to change linking field model.parent to model.parent_id. There is a possibility that brand.name can change and if that happens table models would be unable to link to correct parent.
And I want to do that in bulk, to go through all the records in brand and update all relevant records in models.
UPDATE
m
SET
parent_id = b.id
FROM
models m
JOIN
brand b ON b.name = m.parent
I'd them assume you want to remove models.parent
ALTER TABLE models DROP COLUMN parent
UPDATE models
SET parent_id = brand.id
FROM brand
WHERE brand.name = models.parent