How to list active connections on PostgreSQL? - sql

Is there a command in PostgreSQL to select active connections to a given database?
psql states that I can't drop one of my databases because there are active connections to it, so I would like to see what the connections are (and from which machines)

Oh, I just found that command on PostgreSQL forum:
SELECT * FROM pg_stat_activity;

Following will give you active connections/ queries in postgres DB-
SELECT
pid
,datname
,usename
,application_name
,client_hostname
,client_port
,backend_start
,query_start
,query
,state
FROM pg_stat_activity
WHERE state = 'active';
You may use 'idle' instead of active to get already executed connections/queries.

SELECT * FROM pg_stat_activity WHERE datname = 'dbname' and state = 'active';
Since pg_stat_activity contains connection statistics of all databases having any state, either idle or active, database name and connection state should be included in the query to get the desired output.

You can check connection details in Postgres using pg_stat_activity. You can apply filter to satisfy your condition. Below are queries.
References: https://orahow.com/check-active-connections-in-postgresql/
SELECT * FROM pg_stat_activity WHERE state = 'active';
select * from pg_stat_activity where state = 'active' and datname = 'REPLACE_DB_NAME_HERE';

If you would like to use PgAdmin (for me it is more than convenient), you could do these simple steps. Glad if this is helps
SELECT * FROM pg_stat_activity;

Related

How to combine 2 SQL queries

We have 2 SQL queries we use to look up a database lock from a user login, as sometimes we need to unlock it manually. In short, we run the following query, which will return a few results:
SELECT DISTINCT request_session_id
FROM [view_name]
WHERE [condition1] AND [condition2]
We then take the results one at a time, and run the following query (after updating the #request_session_id variable) until we find the line that shows the correct username in the hostname column of the results (the spid values will correspond to the request_session_id's):
DECLARE #request_session_id int;
SET #request_session_id = 107;
SELECT spid, status, hostname
FROM [view_name]
WHERE spid = #request_session_id
What I would like to accomplish (if possible), is to combine these 2 queries so it will find the request_session_id's, and then automatically runs the second query, showing a results line for each ID found by the first query. I'm pretty new to SQL, but I'm familiar with Powershell, so in powershell I would simply save the results from query 1 to a variable, and then use foreach to cycle those results through query 2. I'm just not sure how I would get to the same end result with SQL.
Thanks in advance for the help.
Andrew
Do you simply want IN?
SELECT spid, status, hostname
FROM [view_name]
WHERE spid IN (SELECT request_session_id
FROM [view_name]
WHERE [condition1] AND [condition2]
);
I would us EXISTS with a correlated subquery. Unlike when using IN, this properly handles the case when the first query returns a request_session_id that is null:
SELECT spid, status, hostname
FROM [view_name] v1
WHERE EXISTS (
SELECT 1
FROM [view_name] v2
WHERE
[condition1]
AND [condition2]
AND v1.spid = v2.request_session_id
)
Note: likely, both [view_name]s belong to different tables; otherwise, the logic would be largely simplified.
Like Gordon said above:
SELECT spid, status, hostname
FROM [view_namea]
WHERE spid IN (SELECT request_session_id
FROM [view_nameb]
WHERE [condition1] AND [condition2]
);
Just use an IN clause to filter the spid values that you want:
SELECT spid, status, hostname
FROM [view_name]
WHERE spid IN (
SELECT request_session_id
FROM [view_name]
WHERE [condition1] AND [condition2]
);
This will return results for spids that match the conditions in the IN sub-query. You don't need to include the DISTINCT there, since that just adds extra processing.

sql temporary tables in rstudio notebook's sql chunks?

I am trying to use temp tables in an sql codechunk in rstudio.
An example: When I select one table and return it into an r object things seem to be working:
```{sql , output.var="x", connection='db' }
SELECT count(*) n
FROM origindb
```
When I try anything with temp tables it seems like the commands are running but returns an empty r data.frame
```{sql , output.var="x", connection='db' }
SELECT count(*) n
INTO #whatever
FROM origindb
SELECT *
FROM #whatever
```
My impression is that the Rstudio notebook sql chunks are just set to make one single query. So my temporary solution is to create the tables in a stored procedure in the database. Then I can get the results I want with something simple. I would prefer to have a bit more flexibility in the sql code chunks.
my db connection looks like this:
```{r,echo=F}
db <- DBI::dbConnect(odbc::odbc(),
driver = "SQL Server",
server = 'sql',
database = 'databasename')
```
Like this question, it will work if you put
set nocount on
at the top of your chunk. R seems to get confused when it's handed back the rowcount for the temp table.
I accomplished my goal using CTEs. As long as you define your CTEs in the order that they will be used it works. It is just like using temp tables with one big exception. The CTEs are gone after the query finishes where temp tables exist until you spid is kill (typically via a disconnect).
WITH CTE_WHATEVER AS (
SELECT COUNT(*) n
FROM origindb
)
SELECT *
FROM CTE_WHATEVER
You can also do this for multiple temp table examples
WITH CTE1 AS (
SELECT
STATE
,COUNTY
,COUNT(*) n
FROM origindb
GROUP BY
STATE
,COUNTY
),
CTE2 AS (
SELECT
STATE
,AVG(n)
,COUNTY_AVG
FROM CTE1
GROUP BY
STATE
)
SELECT *
FROM CTE2
WHERE COUNTY_AVG > 1000000
Sorry for the formatting. I couldn't figure out how to get the carriage returns to work in the code block.
I hope this helps.
You could manage a transaction within the SQL chunk defining a BEGIN and COMMIT clauses. For example:
BEGIN ;
CREATE TABLE foo (id varchar) ;
COMMENT ON TABLE foo IS 'Foo';
COMMIT ;

Can you run an UPDATE and WITH together?

I am trying to run an update on a table, but get an error
ERROR: syntax error at or near "UPDATE"
The query is:
WITH
first_users AS (
select min(created_at) as first_at,
company_id as company_id
from users
group by company_id
)
UPDATE companies
SET first_seen_at = LEAST(first_seen_at,
(SELECT first_at FROM first_users WHERE id = first_users.company_id)
);
Can you not run UPDATEs and WITHs together? Seems weird.
My query is actually slightly more complex, which is why I am using the with syntax. When I run SELECT * FROM first_users instead of UPDATE, it works, so there's something wrong with the UPDATE keyword or something.
I would suggest changing this to an update . . . from in any case. There is no reason to update records that do not match. So:
update companies
set first_seen_at = u.first_at
from (select company_id, min(created_at) as first_at
from users
group by company_id
) u
where companies.id = u.company_id and
u.first_seen_at < companies.first_seen_at;
Postgres started supporting CTEs with updates in version 9.1 (http://www.postgresql.org/docs/9.1/static/sql-update.html vs http://www.postgresql.org/docs/9.0/static/sql-update.html). This method is better because it filters the rows before the update.
Try encapsulating the query qith BEGIN/END. I don't know about PostgreSql, but MsSql does not accept WITH without BEGIN/END...

How to find the users list in oracle 11g db?

How to find out the users list, which is all created in the oracle 11g database. Is there any command to find out the users list which we can execute from the Command line interface!
I am not sure what you understand by "execute from the Command line interface", but you're probably looking after the following select statement:
select * from dba_users;
or
select username from dba_users;
select * from all_users
This will work for sure
The command select username from all_users; requires less privileges
You can try the following: (This may be duplicate of the answers posted but I have added description)
Display all users that can be seen by the current user:
SELECT * FROM all_users;
Display all users in the Database:
SELECT * FROM dba_users;
Display the information of the current user:
SELECT * FROM user_users;
Lastly, this will display all users that can be seen by current users based on creation date:
SELECT * FROM all_users
ORDER BY created;
You can think of a mysql database as a schema/user in Oracle. If you have the privileges, you can query the DBA_USERS view to see the list of schema.
I tried this query and it works for me.
SELECT username FROM dba_users
ORDER BY username;
If you want to get the list of all that users which are created by end-user, then you can try this:
SELECT username FROM dba_users where Default_TableSpace not in ('SYSAUX', 'SYSTEM', 'USERS')
ORDER BY username;

Use same alias for union query SQL

So I came across a problem/question yesterday.
I am building a chat (with AJAX) and use two tables:
TABLE users -> 'name', 'username', 'password', 'time'
TABLE messages -> 'sendFrom', 'sendTo', 'message', 'time'
So an example message now would be
'foo' | 'bar' | 'Hey, how are you?' | 130611134427611
I was told the correct way to do this is, instead, to use an ID column, and use that as a Primary Key instead of the username (which, anyway, makes sense).
OK, so now this looks like
TABLE users -> 'ID', 'name', 'username', 'password', 'time'
TABLE messages -> 'sendFrom', 'sendTo', 'message', 'time'
So an example message now would be
'22' | '7' | 'Hey, how are you?' | 130611134427611
I've managed to JOIN both tables to return the rows as on the first example message, but since I am detecting user keypresses too, I need to scan the table twice, so:
SELECT *
FROM (SELECT *
FROM (SELECT *
FROM messages
WHERE sendTo = '$username'
AND time > (SELECT time FROM users
WHERE username = '$username' LIMIT 1)
AND message <> '$keypressCode'
ORDER BY time DESC LIMIT 30)
ORDER BY time ASC)
UNION
SELECT *
FROM (SELECT *
FROM messages
WHERE message = '$keypressCode'
AND time > (SELECT time FROM users
WHERE username = '$username' LIMIT 1)
AND sendTo = '$username' LIMIT 1);
But now, of course, I don't just select from messages; instead, I use a long query like
SELECT * FROM (
SELECT u1.ID as sendTo, u2.ID as sendFrom, messages.message, .....
.....
.....
.....
.....
) as messages;
that MUST BE INSERTED just in the place of messages (I haven't tried this yet, but I think is like that. See, the thing is I DuckDuckGo'ed and Googled and found nothing, so I came here)
My first question is:
Is there a way to use ALIAS for the table messages so I don't have to scan it TWICE? So, instead, I just save the above query using ALIAS as a table called messages and select data from it twice, once in each part of UNION.
In addition, the answer to the first question would also be an answer for:
Is there a way to use ALIAS to save the time selected from the table? (since, again, I am searching for it TWICE).
In practice, what I am doing may not be unefficient (since there will be at most 20 users), but what if?
Also, I am a mathematician, and like it or not, I like to worry a lot about efficiency!
Thank you so much in advance, I hope I made myself clear.
I am not sure but it does look as if you want a view.
Define that query like this:
CREATE VIEW MyMessageView
AS
SELECT ...
FROM ...
...
Now you can use that view in any context where an ordinary table can be used: in a FROM clause, in a JOIN clause, as a subquery etc.:
SELECT ...
FROM MyMessageView
WHERE ...
...
UNION
SELECT ...
FROM MyMessageView
WHERE ...
Instead of using UNION, put an OR in the condition:
SELECT *
FROM messages
WHERE time > (SELECT time FROM users
WHERE username = '$username' LIMIT 1)
AND (message <> '$keypressCode' AND sendTo = '$username'
OR message = '$keypressCode')
I am answering my own question, since I consider what people might be looking for is a VIEW.
First, define that query like this:
CREATE VIEW MyViewTable
AS
SELECT ...
FROM ...
...
...;
Now you can use that view (which is a sepparate query) in any context where an ordinary table can be used: in a FROM clause, in a JOIN clause, as a subquery etc.:
SELECT ...
FROM MyViewTable
WHERE ...
...
UNION
SELECT ...
FROM MyViewTable
WHERE ...
but with a few restrictions:
You cannot SELECT from your view using subqueries, such as
SELECT * FROM MyViewTable WHERE someColumn = (SELECT ... ...)
but (as normal) you can use subqueries when creating the VIEW and in the main query.
The SELECT statement cannot refer to prepared statement parameters.
The definition cannot refer to a TEMPORARY table, and you cannot create a TEMPORARY view.
(there are more, but this are, in my opinion, among the most common queries, so the restrictions might be among the most common errors. See SQLite reference for more information. ).