insert 2 select sql result into one insert sql - sql

i have a table with 2 fields. How can i insert those 2 fields from result of 2 sql result.
insert into access (user,page)
(select id as user from users where id =5,
select pagename as page from pages where id =10)
There is no relation between 2 tables . i dont think i can join .

insert into access ("user", page) values
( (select id as user from users where id =5),
(select pagename as page from pages where id =10)
)

insert into access (user,page)
select users.id as user,
pages.pagename as page
from users,pages
where users.id = 5
and pages.id = 10

Related

How to merge users in PostgreSQL

I need to make something to merge some users in PGSQL but I think that pgsql don't own the MERGE property. I just want to know how to make two users to be matched like this :
id | name | username | mail
1 | toto | tata | toto.tata#gmail.com
2 | titi | tutu | titi.tutu#gmail.com
Here I want to chose which data I would like I want to say that I want to merge only username from 2 to 1 so the result would be :
id | name | username | mail
1 | toto | tutu | toto.tata#gmail.com
You just need to select all the columns for first id and the column you need with second id will be a subquery in select list. Please check below answer for selecting merged result.
Schema and insert statements:
create table users (id int , name varchar(50), username varchar(50), mail varchar(50));
insert into users values (1 , 'toto' , 'tata' , 'toto.tata#gmail.com');
insert into users values (2 , 'titi' , 'tutu' , 'titi.tutu#gmail.com');
Query:
select id,name,(select username from users where id=2) username,mail from users where id=1
Output:
id
name
username
mail
1
toto
tutu
toto.tata#gmail.com
db<fiddle here
To merge the rows within the table you can first update first row with data from second row then delete the second row. Try this:
Schema and insert statements:
create table users (id int , name varchar(50), username varchar(50), mail varchar(50));
insert into users values (1 , 'toto' , 'tata' , 'toto.tata#gmail.com');
insert into users values (2 , 'titi' , 'tutu' , 'titi.tutu#gmail.com');
Update query:
update users set username=(select username from users where id=2) where id=1;
delete from users where id=2;
Select query:
select * from users
id
name
username
mail
1
toto
tutu
toto.tata#gmail.com
db<fiddle here
You could use aggregation:
select min(id) as id,
max(name) filter (where id = 1) as name,
max(username) filter (where id = 2) as username,
max(mail) filter (where id = 1) as mail
from t
where id in (1, 2);
This assumes that you want to pull particular column values from particular ids.
Or you could use join:
select t1.id, t1.name, t2.username, t1.mail
from t t1 join
t t2
on t1.id = 1 and t2.id = 2;
If you actually want to change the data, use update and delete:
update t t1
set username = t2.username
from t t2
where t1.id = 1 and t2.id = 2;
delete from t
where t.id = 2;
Here is a db<>fiddle.

How to pulls related values in PostgreSQL?

Here is my problem.
I have two tables like user and customer. Users can be related to some customer(s).
For example, I have a user who relates to two customers, and the other user relates to three customers, etc.
This is my code that creating tables and inserting values;
create table tbl_user
(
id int,
username varchar(100),
relatedcustom_id int
)
create table tbl_custom
(
id int,
name varchar(100)
)
insert into tbl_custom values(1,'john'),
(2,'adam'),
(3,'steve'),
(4,'marliyn'),
(5,'coco'),
(6,'George');
insert into tbl_user values (1,'cst_moose',1),
(1,'cst_moose',2),
(2,'cst_moose',3),
(3,'cst_kevin',2),
(4,'cst_kevin',5),
(5,'cst_donald',1),
(6,'cst_donald',2),
(7,'cst_donald',4),
(8,'cst_henry',1),
(9,'cst_henry',6),
(10,'cst_michel',1),
(11,'cst_michel',2);
I want to pull the user name(s) that relates to customers that id is 1 and 2.
Here is my select code;
select username from tbl_user where exists (select 1 from tbl_custom
where
id in(1,2))
except
select username from tbl_user where exists (select 1 from tbl_custom
where
id not in(1,2))
But this query demonstrates nothing.
The other select code ;
select username from tbl_user where relatedcustom_id in (1,2)
except
select username from tbl_user where relatedcustom_id not in (1,2)
This query shows like this;
username
--------
cst_michel
What I want to do is a Select - As - From with the following fields
username
--------
cst_michel
cst_moose
cst_donald
I want to pull the user name(s) that relates to customers that id is 1 and 2.
You can use aggregation and having:
select username
from tbl_user
group by username
having sum( (relatedcustom_id = 1)::int ) > 0 and
sum( (relatedcustom_id = 2)::int ) > 0 and
sum( (relatedcustom_id not in (1, 2)::int ) ) = 0;
One of the possible solution is to use arrays:
select username
from tbl_user
where relatedcustom_id in (1,2) -- to filter out unrelated data
group by username
having array[1,2] <# array_agg(relatedcustom_id);
-- or '{1,2}' <# array_agg(relatedcustom_id);

Join Query in Sql server

I am having trouble with a join in sql.
I have 3 tables.
1: Lists the user details
2: Lists the permissions the user group has
3: Lists the page that that group can access
Table1 users :
****************************************
username | group
****************************************
admin | administrator
Table2 groups :
*********************************************
user_group | create | view | system_admin
*********************************************
administrator | 1 | 0 | 1
Table3 urls:
*********************************************
create | view | system_admin
*********************************************
create.php | view.php | system.php
(apologies for my table drawing)
What I am doing via php , is grabbing the user_group they belong to.
I then need to check if they have access to the page they have just hit or redirect them back.
Can I accomplish this with the current table layout the way they are through a join?, Or shall I look to re-design these tables as they are not intuitive for this kind of thing.
I actually might redesign the tables to make them easier to query:
create table users
(
id int,
username varchar(10),
groupid int
);
insert into users values (1, 'admin', 1);
create table groups
(
groupid int,
groupname varchar(20)
);
insert into groups values (1, 'administrator');
create table permissions
(
permissionid int,
permissionname varchar(20)
);
insert into permissions values (1, 'create');
insert into permissions values (2, 'view');
insert into permissions values (3, 'system_admin');
create table urls
(
urlid int,
name varchar(10)
);
insert into urls values(1, 'create.php');
insert into urls values(2, 'view.php');
insert into urls values(3, 'system.php');
create table group_permission_urls
(
groupid int,
permissionid int,
urlid int
);
insert into group_permission_urls values(1, 1, 1);
insert into group_permission_urls values(1, 0, 2);
insert into group_permission_urls values(1, 3, 3);
Then your query would be similar to this:
select *
from users us
left join groups g
on us.groupid = g.groupid
left join group_permission_urls gpu
on us.groupid = gpu.groupid
left join permissions p
on gpu.permissionid = p.permissionid
left join urls u
on gpu.urlid = u.urlid
see SQL Fiddle with Demo
By comparing the $current_page with the results of an IN() subquery, you can do this in one query. If the page matches any listed in a column the user has permission for, this will return a row. It should not return any row if there is no match in an allowed column.
SELECT
groups.create,
groups.view,
groups.system_admin,
1 AS can_access
FROM
users
JOIN groups ON users.group = groups.user_group
WHERE
users.username = '$some_username'
AND (
/* Substitute the current page. Better, use a prepared statement placeholder if your API supports it */
(groups.create = 1 AND '$current_page' IN (SELECT DISTINCT create FROM urls))
OR
(groups.view = 1 AND '$current_page' IN (SELECT DISTINCT view FROM urls))
OR
(groups.system_admin = 1 AND '$current_page' IN (SELECT DISTINCT system_admin FROM urls))
)
This works by comparing the $current_page to the distinct set of possible values from each of your 3 columns. If it matches a column and also the user's group has permission on that type, a row is returned.
select case when count(1) > 0 then 'come in' else 'go away' end
from users, groups, urls
where
users.username = '$username' and
users.user_group = groups.user_group and
((urls.create = '$url' and groups.create = 1) or
(urls.view = '$url' and groups.view = 1) or
(urls.system_admin = '$url' and groups.system_admin = 1))

SQL 2008: Insert multiple rows based on specific criteria

I am trying to clone user permissions. The permissions are driven from a table with only 2 columns, userid and groupid. Both are foreign keys.
Is it possible to insert multiple rows based on criteria? Let's say:
USERID GROUPID
1 A
1 B
1 C
1 D
I would like to insert rows to give USER 2 the same GROUPS as USER 1.
Does this get me close?
INSERT INTO ide_usergroup_assoc (userid, groupid)
VALUES ('USERID I PROVIDE', (SELECT ide_usergroup_assoc.groupid from ide_usergroup_assoc WHERE ide_usergroup_assoc.userid = 'USERID TO BE CLONED'))
insert into ide_usergroup_assoc (userid, groupid)
select 2, groupid
from ide_usergroup_assoc
where userid = 1

SQL - Is there a query that will do "foreach A in table, if !B, insert B"?

I have a table with 2 columns:
nid realm
1 domain_id
1 domain_site
2 domain_id
3 domain_id
I want every entry to have 1 entry for domain id, and 1 for domain site. So I want to end up with:
nid realm
1 domain_id
1 domain_site
2 domain_id
2 domain_site
3 domain_id
3 domain_site
If I was doing this in PHP, I'd just foreach through the whole list and insert the extra line whenever it didn't exist. Unfortunately I only have PHPmyAdmin access to this DB. Is there a way to do this in straight SQL?
(If it makes a difference: The table has about 3000 rows currently, of which I think about 2000 will need the extra line inserted. Also, this is a one-time thing so it does not need to be optimized/uber-slick.)
INSERT IGNORE INTO `table`
SELECT `alt1`.`nid`, `alt2`.`realm`
FROM `table` AS `alt1`, `table` AS `alt2`
I think this will do it, but I don't have a place to test it right now and I'm used to Sql Server rather than MySQL:
INSERT INTO `table`
SELECT id.nid, r.realm
FROM (SELECT nid FROM `table` GROUP BY nid) id
CROSS JOIN (SELECT realm FROM `table` GROUP BY realm) r
LEFT JOIN `table` t ON t.nid=id.nid AND t.realm=r.realm
WHERE t.realm IS NULL
insert into MyTable
(nid, realm)
select nid, 'domain_id'
from MyTable m where not exists (
select 1
from MyTable
where MyTable.nid = m.nid and realm = 'domain_id'
)
union all
select nid, 'domain_site'
from MyTable m where not exists (
select 1
from MyTable
where MyTable.nid = m.nid and realm = 'domain_site'
)
If you have a UNIQUE constraint over (nid, realm), you could do this:
INSERT IGNORE INTO nidTable (nid, realm)
SELECT nid, 'domain_site'
FROM nidTable WHERE realm = 'domain_id';