Postgresql count unique conversation [duplicate] - postgresql

This question already has answers here:
MYSQL select DISTINCT values in two columns
(8 answers)
Closed 5 years ago.
Hello i have some table like this:
Text | from | to
A | 1 | 2
B | 2 | 1
C | 3 | 1
D | 1 | 4
And i would like to get number of conversations, so for this example it should be 3. Do anyone know how to do it? Thank you.
One more information - i decided to use UUID so i switched to PostgreSQL and there is no least and greatest.

SELECT * FROM your_table_name name_of_you_like_to_select
WHERE name_of_you_like_to_select.from = 3;
You can use some SQL query like this.

Related

How to get multiple columns with a single group by in Postgres?

I have a table that looks like below
Table "public.test_systems"
Column | Type | Modifiers
-----------------------------+------------------------+-----------
rid | integer | not null
r_osname | character varying(255) |
r_health | integer |
r_patch | bigint |
r_loc | character varying(255) |
Here each row in the table depicts a system. Now if I want to find out how many systems by unique OS names, I do a query like below
select r_osname, count(*) as total_systems from test_systems group by r_osname;
So I get a result like below
r_osname | total_systems
-----------------------------------------------+--------------
Ubuntu 18.04.4 LTS | 18
Windows 10 Pro | 2
CentOS Linux | 1
Windows Server 2019 | 3
Mac OS X - High Sierra | 2
Now I want to run the same query but for multiple columns. In other words I want to get multiple columns with a single groupby. But Postgres forces me to mention the additional columns in the groupby too.
I tried distinct on in my query like below
select distinct on (r_osname) test_systems.* from test_systems order by os_name;
I got same number of rows (partial success) but can't get the count(*) as an additional column.
The final result could look something like below (on including additional columns like r_health and r_loc)
r_osname | r_health | r_loc | total_systems
-----------------------------------------------+-----------------------------------+--------------------+--------------
Ubuntu 18.04.4 LTS | 1012 | NYC | 18
Windows 10 Pro | 1121 | LON | 2
CentOS Linux | 1255 | DEL | 1
Windows Server 2019 | 1451 | HYD | 3
Mac OS X - High Sierra | 1120 | LA | 2
How do I get the expected result?
You need a window function to make this work:
SELECT DISTINCT
r_osname, r_health, r_loc,
count(*) OVER (PARTITION BY r_osname, r_health, r_loc)
FROM test_systems
Depending on which combination of values in the columns you want to include in the result you can play with the DISTINCT ON (...) clause. Without a DISTINCT clause you will get as many rows as there are in the table (26 in your example) but if you want only 1 row for each OS then you should use DISTINCT ON (r_osname). The row that will be returned depends on the ORDER BY clause - if none is given then the first row will be returned for each set of rows which have the same r_osname but there will be no way to predict which row that will be.

PostgreSQL arabic case insensitive

I am looking for how to search a database using Arabic text. In Arabic there are some letters that can be written in different ways but in the results they should all show up if one of them is included in the where clause.
The famous example for this would be:
SELECT * FROM persons WHERE name = "اسامة";
+----+--------------+
| id | name |
+----+--------------+
| 3 | أسامه |
| 4 | أسامة |
| 5 | اسامه |
| 6 | اسَامه |
+----+--------------+
4 rows in set (0.00 sec)
I found a good and probably most performant way to do this by creating a custom collation on MySQL in this article but I have no idea how that is done or if it is possible at all in PostgreSQL.
Other ways that include changing the query itself to use Regex are not useful for my use case.
Can someone please guide me how to do the same

Graph in Grafana using Postgres Datasource with BIGINT column as time

I'm trying to construct very simple graph showing how much visits I've got in some period of time (for example for each 5 minutes).
I have Grafana of v. 5.4.0 paired well with Postgres v. 9.6 full of data.
My table below:
CREATE TABLE visit (
id serial CONSTRAINT visit_primary_key PRIMARY KEY,
user_credit_id INTEGER NOT NULL REFERENCES user_credit(id),
visit_date bigint NOT NULL,
visit_path varchar(128),
method varchar(8) NOT NULL DEFAULT 'GET'
);
Here's some data in it:
id | user_credit_id | visit_date | visit_path | method
----+----------------+---------------+---------------------------------------------+--------
1 | 1 | 1550094818029 | / | GET
2 | 1 | 1550094949537 | /mortgage/restapi/credit/{userId}/decrement | POST
3 | 1 | 1550094968651 | /mortgage/restapi/credit/{userId}/decrement | POST
4 | 1 | 1550094988557 | /mortgage/restapi/credit/{userId}/decrement | POST
5 | 1 | 1550094990820 | /index/UGiBGp0V | GET
6 | 1 | 1550094990929 | / | GET
7 | 2 | 1550095986310 | / | GET
...
So I tried these 3 variants (actually, dozens of others with no luck) with no success:
Solution A:
SELECT
visit_date as "time",
count(user_credit_id) AS "user_credit_id"
FROM visit
WHERE $__timeFilter(visit_date)
ORDER BY visit_date ASC
No data on graph. Error: pq: invalid input syntax for integer: "2019-02-14T13:16:50Z"
Solution B
SELECT
$__unixEpochFrom(visit_date),
count(user_credit_id) AS "user_credit_id"
FROM visit
GROUP BY time
ORDER BY user_credit_id
Series ASELECT
$__time(visit_date/1000,10m,previous),
count(user_credit_id) AS "user_credit_id A"
FROM
visit
WHERE
visit_date >= $__unixEpochFrom()::bigint*1000 and
visit_date <= $__unixEpochTo()::bigint*1000
GROUP BY 1
ORDER BY 1
No data on graph. No Error..
Solution C:
SELECT
$__timeGroup(visit_date, '1h'),
count(user_credit_id) AS "user_credit_id"
FROM visit
GROUP BY time
ORDER BY time
No data on graph. Error: pq: function pg_catalog.date_part(unknown, bigint) does not exist
Could someone please help me to sort out this simple problem as I think the query should be compact, naive and simple.. But Grafana docs demoing its syntax and features confuse me slightly.. Thanks in advance!
Use this query, which will works if visit_date is timestamptz:
SELECT
$__timeGroupAlias(visit_date,5m,0),
count(*) AS "count"
FROM visit
WHERE
$__timeFilter(visit_date)
GROUP BY 1
ORDER BY 1
But your visit_date is bigint so you need to convert it to timestamp (probably with TO_TIMESTAMP()) or you will need find other way how to use it with bigint. Use query inspector for debugging and you will see SQL generated by Grafana.
Jan Garaj, Thanks a lot! I should admit that your snippet and what's more valuable your additional comments advising to switch to SQL debugging dramatically helped me to make my "breakthrough".
So, the resulting query which solved my problem below:
SELECT
$__unixEpochGroup(visit_date/1000, '5m') AS "time",
count(user_credit_id) AS "Total Visits"
FROM visit
WHERE
'1970-01-01 00:00:00 GMT'::timestamp + ((visit_date/1000)::text)::interval BETWEEN
$__timeFrom()::timestamp
AND
$__timeTo()::timestamp
GROUP BY 1
ORDER BY 1
Several comments to decypher all this Grafana magic:
Grafana has its limited DSL to make configurable graphs, this set of functions converts into some meaningful SQL (this is where seeing "compiled" SQL helped me a lot, many thanks again).
To make my BIGINT column be appropriate for predefined Grafana functions we need to simply convert it to seconds from UNIX epoch so, in math language - just divide by 1000.
Now, WHERE statement seems not so simple and predictable, Grafana DSL works different where and simple division did not make trick and I solved it by using another Grafana functions to get FROM and TO points of time (period of time for which Graph should be rendered) but these functions generate timestamp type while we do have BIGINT in our column. So, thanks to Postgres we have a bunch of converter means to make it timestamp ('1970-01-01 00:00:00 GMT'::timestamp + ((visit_date/1000)::text)::interval - generates you one BIGINT value converted to Postgres TIMESTAMP with which Grafana deals just fine).
P.S. If you don't mind I've changed my question text to be more precise and detailed.

Conditional expression, postgresql, get the result from the case [duplicate]

This question already has answers here:
Why can't I use column aliases in the next SELECT expression?
(4 answers)
Join Alias Columns SQL
(1 answer)
PostgreSQL does not accept column alias in WHERE clause
(1 answer)
Closed 4 years ago.
Looking at conditional expressions in Postgresql. To be more precise, this example.
SELECT * FROM test;
a
---
1
2
3
SELECT a,
CASE WHEN a=1 THEN 'one'
WHEN a=2 THEN 'two'
ELSE 'other'
END AS amod
FROM test;
a | amod
---+-------
1 | one
2 | two
3 | other
I cant seem to find out how to now access the result under amod(one, two and other). After searching around, I haven't been able to find a way to solve it. Any pointers on how to do it?
EDIT: What I'm looking for is to be able to SELECT amod FROM the case expression and get it out as a table.

Select distinct rows from MongoDB

How do you select distinct records in MongoDB? This is a pretty basic db functionality I believe but I can't seem to find this anywhere else.
Suppose I have a table as follows
--------------------------
| Name | Age |
--------------------------
|John | 12 |
|Ben | 14 |
|Robert | 14 |
|Ron | 12 |
--------------------------
I would like to run something like SELECT DISTINCT age FROM names WHERE 1;
db.names.distinct('age')
Looks like there is a SQL mapping chart that I overlooked earlier.
Now is a good time to say that using a distinct selection isn't the best way to go around querying things. Either cache the list in another collection or keep your data set small.