Insert rows depending on select query return - sql

i have a table user activity ( iuser_id, sactivity)
I would need to insert multiple instances to this table using user id ids from table user whose job is X . How do I do that?
Insert into tbluseractivity
(Select iuser_id from tbl_user where activity = x , 'sample activity')
Given that tbl_user would return 100 records, how can insert it.thank you.

You can bulk insert as below
insert into tbluseractivity(iuser_id, sactivity)
Select iuser_id, 'sample activity'
from tbl_user
where activity = x

Related

Postgresql - Insert when select return something

Is it possible to run select query, check if row exist and then insert some values? I would like to do that in one query. I think about SELECT .. CASE .. THEN, for example:
SELECT user_id, CASE when user_id > 0 then (INSERT INTO another_table ...) ELSE return 0 END
FROM users WHERE user_id = 10
Now I'm able to do that with 2 queries, first do SELECT and second INSERT values (if first query return something).
Thanks!
in general the construct is:
INSERT INTO another_table
SELECT value1,value2..etc
where exists (SELECT user_id FROM users WHERE user_id = 10)
or in this particular case:
INSERT INTO another_table
SELECT value1,value2..etc
FROM users WHERE user_id = 10
If no such user, no rows will be selected and so inserted

SQL 'GROUP BY' to filter an array of 'text' data type

I am new to SQL and I an trying to understand the GROUP BY statement.
I have inserted the following data in SQL:
CREATE TABLE table( id integer, type text);
INSERT INTO table VALUES (1,'start');
INSERT INTO table VALUES (2,'start');
INSERT INTO table VALUES (2,'complete');
INSERT INTO table VALUES (3,'complete');
INSERT INTO table VALUES (3,'start');
INSERT INTO table VALUES (4,'start');
I want to select those IDs that do not have a type 'complete'. For this example I should get IDs 1, 4.
I have tried multiple GROUP BY - HAVING combinations. My best approach is:
SELECT id from customers group by type having type!='complete';
but the resulted IDs are 4,3,2.
Could anyone give me a hint about what I am doing wrong?
You are close. The having clause needs an aggregation function and you need to aggregate by id:
select id
from table t
group by id
having sum(case when type = 'complete' then 1 else 0 end) = 0;
Normally, if you have something called an id, you would also have a table with that as primary key. If so, you can also do:
select it.id
from idtable it
where not exists (select 1
from table t
where t.type = 'complete' and it.id = t.id
);

Return value cross join

I have two tables, one is a table #1 contains user information, email, password, etc..
the other table #2 contains item information
when I do a insert into table #2, and then use the returning statement, to gather what was inserted (returning auto values as well as other information), I also need to return information from table #1.
(excuse the syntax)
example:
insert into table #1(item,user) values('this item','the user')
returning *, select * from table 2 where table #1.user = table #2.user)
in other words, after the insert I need to return the values inserted, as well as the information about the user who inserted the data.
is this possible to do?
the only thing I came up with is using a whole bunch of subquery statements in the returning clause. there has to be a better way.
I suggest a data-modifying CTE (Postgres 9.1 or later):
WITH ins AS (
INSERT INTO tbl1(item, usr)
VALUES('this item', 'the user')
RETURNING usr
)
SELECT t2.*
FROM ins
JOIN tbl2 t2 USING (usr)
Working with the column name usr instead of user, which is a reserved word.
Use a subquery.
Simple demo: http://sqlfiddle.com/#!15/bcc0d/3
insert into table2( userid, some_column )
values( 2, 'some data' )
returning
userid,
some_column,
( SELECT username FROM table1
WHERE table1.userid = table2.userid
);

insert 2 select sql result into one insert 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

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))