I have the following Postgres tables
users table:
id |
-----|
user_follows table (old table):
follower_id | following_id
------------|--------------
communities table (new table):
id | owner_id
-----|-----------
community_members table (new table):
community_id | member_id
-------------|------------
The communities already exist each having an owner_id. I'm trying to construct a SQL statement that will move data from user_follows into community_members given a community owner's id. The following_id should be the owner_id and the follower_id should be the member_id
follower_id, following_id, owner_id, and member_id are all reference to the users table id.
Thanks!
edit: This is what I'm currently thinking
INSERT INTO community_members (community_id, member_id)
SELECT communities.id, user_follows.follower_id
FROM communities JOIN user_follows
WHERE communities.owner_id = 123
AND user_follows.following_id = 123;
``
I figured it out. The working query is
INSERT INTO community_members (community_id, member_id)
SELECT communities.id, user_follows.follower_id
FROM communities JOIN user_follows
ON communities.owner_id = user_follows.following_id
It would be cool to be able to do this for every user that is a community owner automatically, instead of having to run the query for each one. This is ok for now as there are <15 users I need to run this for
edit: Have updated to run for all community owners
Related
There are clients(companies) and contacts in two tables. Both contacts and clients have their own fields. But they all have an id that is a primaryKey. In addition, there are "links" between clients and contacts - each client can be assigned a contact and vice versa. There is a third table for this, called 'assignment', which has only two fields - company id and contact id.
Suppose we have linked a contact with id 3 to a company with id 12076. Next, we have linked a contact with id 10, and the last contact with id 5. Сheck our result:
SELECT contactId FROM assignment WHERE companyId = 12076;
The result is correct -
After these steps, at some point I need to get the FIELDS of contacts associated with the company I need. There is a company 12076, I need to get all the contact fields associated with it. I made a request like this:
SELECT id, fullName FROM contacts WHERE contacts.rowid IN (SELECT contactId FROM assignment WHERE companyId = 12076);
This request displays the contacts I need and their fields. Exactly 3 contacts, but there is one problem - they are displayed in sorted order, sorted by id.
I need the contact fields to be displayed in the order in which they were added. How can i dow this? Maybe i need to use JOIN?
By default an SQLite table has a Rowid column. We can use this column in ORDER BY.
If we want the ContactId's in the order they were inserted into the table contacts we can join onto contacts and order by it's Rowid.
See [https://www.sqlitetutorial.net/sqlite-autoincrement/][1]
create table companies(id int);
create table contacts (id int);
create table assignment(companyId int,contactId int);
insert into companies values(12076);
insert into contacts values(10),(3),(5);
insert into assignment values (12076,3),(12076,10),(12076,5);
SELECT a.contactId
FROM assignment a
JOIN contacts c
on a.contactId = c.id
WHERE companyId = 12076
order by c.Rowid;
| contactId |
| --------: |
| 10 |
| 3 |
| 5 |
db<>fiddle here
I have a table/sql issue I don't know how to solve.
I need to update/create a table of user ids with order ids.
Therefore I have to get a new user_id, by searching for the email in an old list.
With the email adress I need to look up the new user id.
So the logic is like:
order_id -> look at the old user_id -> look at the email -> look at the new user_id
I tried to create an example:
---------------------
TABLE: USERS_OLD (a list of user ids and an email adress)
id email
1 test1#email.com
2 test2#email.com
3 test3#email.com
4 test4#email.com
---------------------
---------------------
TABLE: USER_ORDERS_OLD (the connection of an order id with a user id)
user_id order_id
1 DLEFGM
2 OPDFGT
3 UZDFGP
4 POIDSX
---------------------
---------------------
TABLE: USERS_NEW (a new list of users id with the same emails from table USERS_OLD)
id email
5 test1#email.com
9 test2#email.com
10 test3#email.com
17 test4#email.com
---------------------
What I want to create:
---------------------
TABLE: USER_ORDERS_NEW
user_id order_id
5 DLEFGM
9 OPDFGT
10 UZDFGP
17 POIDSX
---------------------
I have no idea how to do that action. I don't even know what to search for.
What I managed to do is a LEFT JOIN sql statement to compare the user ids and create a list of matching user_ids.
But I have no idea how to look up over even more tables...
Hopefully someone can help me.
If it's easier I could also try to do it in spreadsheets.
Thanks in advance!
Assuming you just want to return the query then use;
SELECT u3.id, u2.order_id
FROM USERS_OLD u1
JOIN USER_ORDERS_OLD u2 ON u1.id = u2.user_id
JOIN USERS_NEW u3 ON u1.email = u3.email;
However, if you want to write the result into a new table, then you need to create the table first.
CREATE TABLE USER_ORDERS_NEW (user_id INTEGER, order_id VARCHAR(50));
INSERT INTO USER_ORDERS_NEW (user_id, order_id)
SELECT u3.id, u2.order_id
FROM USERS_OLD u1
JOIN USER_ORDERS_OLD u2 ON u1.id = u2.user_id
JOIN USERS_NEW u3 ON u1.email = u3.email;
See Demo
With your example you should be able to accomplish this with this query
INSERT INTO user_orders_new (user_id, order_id) SELECT usr_new.id, ord_old.order_id
FROM users_old usr_old JOIN users_new usr_new ON usr_new.email = usr_old.email
JOIN user_orders_old ord_old ON ord_old.user_id = usr_old.id;
You may want to opt for a LEFT JOIN on the old order table if you intend to migrate the ids regardless of whether they have had an order or not although I assume that's not the intention to populate the new order table with new users ids that haven't made an order.
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)
I want to move data from these old tables
restaurant_id | restaurant_nm | more data
bar_id | bar_nm | more data
To
venue_id | venue_nm
I'll add field venue_id to the old tables
Then I want to run a query similar to this:
INSERT INTO `venue` (SELECT null, `restaurant_nm` FROM `restaurant`)
However, while do the copy I want the new id to be stored into the old table. Is this possible with pure mysql?
Edit The old restaurants can be chains (multiple messy joe's), the only thing that identifies them 100% is the id
You could temporarily store the old ID in the new table (in an extra column) and then do an UPDATE on the old table. That's two lines of 'pure SQL.'
restaurant_id |restaurant_name | v_id
venue_id | venue_name | rest_id
INSERT INTO `venue` (SELECT null, `restaurant_nm`, `restaurant_id` FROM `restaurant`)
and then
UPDATE restaurant r
INNER JOIN venue v
ON r.restaurant_id = v.rest_id
SET r.v_id = v.venue_id
Interested to see what a more elegant solution might be.
Take for example an application which has users, each of which can be in exactly one group. If we want to SELECT the list of groups which have no members, what would be the correct SQL? I keep feeling like I'm just about to grasp the query, and then it disappears again.
Bonus points - given the alternative senario, where it's a many to many pairing, what is the SQL to identify unused groups?
(if you want concrete field names:)
One-To-Many:
Table 'users': | user_id | group_id |
Table 'groups': | group_id |
Many-To-Many:
Table 'users': | user_id |
Table 'groups': | group_id |
Table 'user-group': | user_id | group_id |
Groups that have no members (for the many-many pairing):
SELECT *
FROM groups g
WHERE NOT EXISTS
(
SELECT 1
FROM users_groups ug
WHERE g.groupid = ug.groupid
);
This Sql will also work in your "first" example as you can substitute "users" for "users_groups" in the sub-query =)
As far as performance is concerned, I know that this query can be quite performant on Sql Server, but I'm not so sure how well MySql likes it..
For the first one, try this:
SELECT * FROM groups
LEFT JOIN users ON (groups.group_id=users.group_id)
WHERE users.user_id IS NULL;
For the second one, try this:
SELECT * FROM groups
LEFT JOIN user-group ON (groups.group_id=user-group.group_id)
WHERE user-group.user_id IS NULL;
SELECT *
FROM groups
WHERE groups.id NOT IN (
SELECT user.group_id
FROM user
)
It will return all group id which not present in user