Query IN Clause with parameter - postgresql

Here is my query,
<Request method="GET">
<Query>
select user_id from user
where user_type in ($userTypes)
</Query>
</Request>
How do I sent multiple values for this parameter $userType in metamug resource file. I'm using a GET request. And my database is postgres.
$userTypes is list of ids. I can pass it as comma separated string "1501,1502,1503" in the request.
Thanks.

You could use:
select user_id from user
where user_type in (SELECT unnest(string_to_array($userTypes, ',')));
DbFiddle Demo

you can also write it as
<Request method="GET">
<Query>
select user_id from user
where user_type =any(string_to_array($userTypes,',')::int[]);
</Query>
</Request>
I've typecast it as Integer array you can use any other datatype as per your need.

Related

Union-all postgresql select clauses preserving order

Having complex SQL query to RDBMS Postgresql which consists of multiple nested UNION ALL-like nested queries, something like this:
(
(
(<QUERY 1-1-1> UNION ALL <QUERY 1-1-2>) UNION ALL
(<QUERY 1-1-3> UNION ALL <QUERY 1-1-4>) UNION ALL
...
) UNION ALL
(
(<QUERY 1-2-1> UNION ALL <QUERY 1-2-2>) UNION ALL
(<QUERY 1-2-3> UNION ALL <QUERY 1-2-4>) UNION ALL
...
) UNION ALL
...
) UNION ALL
(
(
(<QUERY 2-1-1> UNION ALL <QUERY 2-1-2>) UNION ALL
(<QUERY 2-1-3> UNION ALL <QUERY 2-1-4>) UNION ALL
...
) UNION ALL
(
(<QUERY 2-2-1> UNION ALL <QUERY 2-2-2>) UNION ALL
(<QUERY 2-2-3> UNION ALL <QUERY 2-2-4>) UNION ALL
...
) UNION ALL
...
) UNION ALL
(
...
)
Each <QUERY i-th> is relatively lightweight query which produces about 100K-1M rows and can be sorted in-memory without significant performance impact.
Result query is consists of tens thousands multi-level nested UNION ALL queries in strict conventional order, like traversing tree in depth, so result query is several billion rows dataset.
So question is: since SQL does not guarantee order of UNION ALL statement, outer query should contain ORDER BY clause, but server hardware cannot perform sorting of billon rows in required time.
However, order of united queries is strict determined, and should be: <QUERY 1-1-1>, <QUERY 1-1-2> and so on, sorted hierarchically, so in fact sorting of outer query is redundant, since dataset is already sorted by sql query structure.
It's necessary to force Postgres to preserve order of nested UNION ALL statements. How to do it? Any plugins, extensions and even dirty hacks are welcome.
Please avoid of answers and comments mention XY-like problem - question is formulated as-is in research manner. Structure of database and dataset cannot be changed by conditions of question. Thanks.
Try this - allocate the queries' results into a temporary table.
Here it is step by step:
Create a temporary table ex. the_temp_table like the the record type of <QUERY 1-1-1>
create temporary table the_temp_table as <QUERY 1-1-1> limit 0;
Add an auto-increment primary key column extra_id to the_temp_table
alter table the_temp_table add column extra_id serial primary key not null;
Then run all your queries one by one in the right order
insert into the_temp_table <QUERY 1-1-1>; insert into the_temp_table <QUERY 1-1-2>;
insert into the_temp_table <QUERY 1-1-3>; insert into the_temp_table <QUERY 1-1-4>;
insert into the_temp_table <QUERY 1-2-1>; insert into the_temp_table <QUERY 1-2-2>;
insert into the_temp_table <QUERY 1-2-3>; insert into the_temp_table <QUERY 1-2-4>;
-- continue
Finally
select <fields list w/o extra_id> from the_temp_table order by extra_id;
-- no sorting is taking place here
Effectively thus you will be emulating UNION ALL in a controlled manner with an insignificant performance penalty.
There are 2 ways of looking at this:
The safest alternative is be to declare an id column using SERIAL or BIGSERIAL, which will be ordered and indexed. As the records are already ordered there will be a minimal effect on query speed and you will be sure that there are no errors in the ordering.
If the order is not critical, and you don't modify the data at all it will probably be fetched in the same order as you entered it. There is no guarantee. How important is the order to your application?

MyBatis get resultMap as String

I need to get from the database uniqe list if values in one column (type String). But if I try to set
<select id="getAllValues" parameterType="map" resultMap="java.lang.String">
SELECT distinct value_id FROM values
</select>
I receive the error - Result Maps collection does not contain value for java.lang.String
How can I get a list of Stings from the database via MyBatis?
Thanks to ave, I've found the solution:
<select id="getAllValues" parameterType="map" resultType="java.lang.String">
SELECT distinct value_id FROM values
</select>

Someone can tell me for what are grafana "series name column"?

What am I supposed to put in <Series name column>?
I'm trying to do a Pie chart dashboard and I don't know where can I see information for that.
SELECT
UNIX_TIMESTAMP(<time_column>) as time_sec,
<value column> as value,
<series name column> as metric
FROM <table name>
WHERE $__timeFilter(time_column)
ORDER BY <time_column> ASC
For example, you have a table which contains columns 'server_name', 'cpu_load', 'reported_time'. So you can query this using
SELECT
UNIX_TIMESTAMP(reported_time) as time_sec,
cpu_load as value,
server_name as metric
FROM cpu_measurements
WHERE $__timeFilter(reported_time)
ORDER BY time_sec ASC

Applying distinct on more than one field?

I have a SQL query, like so:
SELECT DISTINCT ID, Name FROM Table
This brings up all the distinct IDs (1...13), but in the 13 IDs, it repeats the name (as it comes up twice). The order of the query (ID, Name) has to be kept the same as the app using this query is coded with this assumption.
Is there a way to ensure there are no duplicates?
Thanks
You can try :
select id, name from table group by id,name
But it seems like distinct should work. Perhaps there are trailing spaces at the end of your name fields?
Instead of using DISTINCT, use GROUP BY
SELECT ID, Name FROM Table GROUP BY ID, Name

GROUP BY problem with varchar

There are links stored in a DB as varchars. With these links I want to use GROUP BY.
http://example.com
http://example.com
http://example.com
SQL over that data:
SELECT COUNT(*) c, Url
FROM Advertisements
GROUP BY Url
I want this output:
c Url
3 http://example.com
But instead I get this three times:
c Url
1 http://example.com
Why doesn't SELECT group the varchar fields? They are the same but GROUP BY does not detect that. Any ideas?
If the string containing those URLS is the data that is stored, they are not the same url, each one is differnent therfore group by would put each ina differnt group.
The endings are different
7​i18704
5​i18704
4​i18704
Following your comment I have updated and they GROUP as expected. What do you get when you try this?
CREATE TABLE #Advertisements
(
ID INT IDENTITY(1,1),
Url VARCHAR(200)
)
INSERT INTO #Advertisements VALUES
('http://example.com')
INSERT INTO #Advertisements VALUES
('http://example.com')
INSERT INTO #Advertisements VALUES
('http://example.com')
SELECT COUNT(*) c, Url
FROM #Advertisements
GROUP BY Url
Just like HLGEM and Martin said, the whole text in the field has to be the same so that the GROUP BY works, you can use something like GROUP BY SUBSTRING(Url, 0, 30), this way you'll get:
URL | COUNT
http://example.com | 3