I have been reading the PSQL Documentation and also bothering Google - although I am not sure what to look for - but it doesn't look it is possible to create a tsvector out of a select.
Let me explain a bit. I have table users and I added a tsvector column to it called tsv.
Column | Type | Modifiers
-------------------+-----------------------------+---------------------------------------------------
id | integer | not null default nextval('jobs_id_seq'::regclass)
username | character varying(255) | not null
tsv | tsvector |
Now every user has many articles.
What I want now is to store the articles title as tsvector in the tsv column. Something like this:
UPDATE users SET tsv = to_tsvector(
SELECT string_agg(title)
FROM users INNER JOIN books
ON user.id = articles.user_id
GROUP BY user.id
)
So obviously the query would not work even without trying to make a tsvector out of a SELECT. It has basically 2 "problems"
Thank you very much in advance.
UPDATE users
SET tsv = to_tsvector(s.tsv)
from
(
SELECT id, string_agg(title) tsv
FROM
users
INNER JOIN
articles ON user.id = articles.user_id
GROUP BY user.id
) s
where users.id = s.id
Related
I have following two tables in my potgres database with each type.
user
userid | bigint (PK) NOT NULL
username | character varying(255)
businessname | character varying(255)
inbox
messageid | bigint (PK) NOT NULL
username | character varying(255)
businessname | character varying(255)
What i wanna achieve here is i want to add a new field called userRefId to inbox table and migrate data on user table's userid data into that where each username and businessname match in both tables.
These are the queries i use to do that.
ALTER TABLE inbox ADD userRefId bigint;
UPDATE inbox
SET userRefId = u.userid
from "user" u
WHERE u.username = inbox.username
AND u.businessname = inbox.businessname;
Now i want to verify the data has been migrated correctly. what are the approaches i can take to achieve this? (Note : the username on inbox can be null)
Would this be good enough to verification?
Result of select count(*) from inbox where username is not null; being equal to
select count(userRefId) from inbox;
Is the data transferred correctly? First, the update looks correct, so you don't really need to worry.
You can get all rows in consumer_inbox where the user names don't match
select ci.*. -- or count(*)
from consumer_inbox ci
where not exists (select 1
from user u
where ci.userRefId = u.userId
);
This doesn't mean that the update didn't work. Just that the values in consumer_inbox have no matches.
Under the circumstances of your code, this is equivalent to:
select ci.*
from consumer_inbox ci
where userId is null;
Although this would not pick up a userId set to a non-matching record (cosmic rays, anyone?).
You can also validate the additional fields used for matching:
select ci.*. -- or count(*)
from consumer_inbox ci
where not exists (select 1
from user u
where ci.userRefId = u.userId and
ci.username = u.username and
ci.businessname = u.businessname
);
However, all this checking seems unnecessary, unless you have trigger on the tables or known non-matched records.
I have Problem statement in Apache Phoenix in which I need to combine three tables for the result.
I have three views over Hbase table, Schema is as follow
Table group:-
pk | Title | ownerId | data
Table Members:-
pk | parentId | Email | data
Table userinfo:-
pk | Email | First Name | Last Name
Now, I want to fetch groups whose title matches with input string if not matched then want to fetch groups whose members have a name that matches with the input string.
I already tried query as follow:-
select * from Group where pk like 'Prefix_%'
and (TITLE like '%A%'
or (OWNER_ID in
(
select parentId from MEMBERS where EMAIL in
( select distinct(EMAIL) from USER_INFO
where pk like 'PREFIX%' and
( FIRST_NAME like '%A%' or LAST_NAME like '%A%')
)
)
) ) order by TITLE limit 5;
But, it's taking too much time also tried Left Join Query with similar but not give expected result.
Please Suggest how can I improve this?
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
I feel like an idiot asking this...
Table 1: users
id serial
person integer
username char(32)
Table 2:persons
id serial
name char(16)
Can I run a query that returns the name field in persons by providing the username in users?
users
1 | 1 | larry123
persons
1 | larry
2 | curly
SQL?
select name from persons where users.person=persons.id and users.username='larry123';
with the desired return of
larry
I have been doing it with two passes until now and think maybe a nested select using a join is what I need
1 | larry
It sounds like you're asking how to do a join in SQL:
SELECT
name
FROM
users JOIN persons ON (users.person = persons.id)
WHERE
users.username = 'larry123';
that is almost the query you wrote. All you were missing was the join clause. You could also do that join like this:
SELECT name
FROM users, persons
WHERE
users.person = persons.id
AND users.username = 'larry123';
I suggest finding a well-written introduction to SQL.