PostgreSQL integer array value join to integer in other table with desc string - sql

I have a table test column with int arrays and values like {1000,4000,6000} or {1000} or {1000,4000} called ekw.
These values match to a description string in another table
tab: test
id | name | ekw
-----------------
1 | One | {1000}
2 | Two | {1000,4000}
3 | Three | {1000,4000,6000}
tab: ekwdesc
id | value | desc
-----------------
1 | 1000 | Max
2 | 2000 | Tim
3 | 3000 | Rita
5 | 4000 | Sven
6 | 5000 | Tom
7 | 6000 | Bob
is it possible to select these columns and print the strings?
something like:
select name, ekw from test, ekwdesc
I would like to see this result:
id | name | ekwdesc
-----------------
1 | One | Max
2 | Two | Max, Sven
3 | Three | Max, Sven, Bob
I tried with IN and ANY but couldn't get it to work.

You had the right idea to use the any operator for the join. Once the join is complete, all that's left is to use string_agg to transform the result to the format you want:
SELECT name, STRING_AGG(description, ', ')
FROM test
JOIN ekwdesc ON ekwdesc.value = ANY(test.ekw)
GROUP BY name
See the attached SQLFiddle for an executable example.

Related

Is it possible to add values together that are associated with different row names while keeping other rows intact?

I am trying to add two values together that are associated to two different rows that have different names values. I would normally adds the values using the group function, however the group function only works for matching strings.
| Direction | | Total |
------------+--+--------
| Test1 | | 5000 |
| Test2 | | 3000 |
| Test3 | | 2000 |
Expected outcome (adding Test1 + Test2) while keeping Test 3 in the table:
| Direction | | Total |
--------------+--+--------
| Test1plus2 | | 8000 |
| Test3 | | 2000 |
You would use a conditional expression:
select (case when direction in ('test1', 'test2') then 'test1plus2'
else direction
end) as direction_group,
sum(total) as total
from t
group by direction_group;

How to get every first result of select query in loop iterating over array of strings?

I have a table (e.g. Users) in PostgreSQL database. Its size is relatively large (ca. 4 GB of data) and I would like to get a table/result consisting of single rows fulfilling the select query. This query shall be executed for each element in an array of strings (couple dozens of elements).
Example single select for one element:
SELECT * FROM "Users" WHERE "Surname" LIKE 'Smith%' LIMIT 1
Value between ' and %' should be an element of input array.
EDIT: It doesn't matter for me whether I get record no. 1 or 2 for LIKE 'Smith%'
How can I achieve this?
I tried to append query results to some array variable within FOREACH loop but with no success.
Example source table:
| Id | Name | Surname |
|---- |-------- |---------- |
| 1 | John | Smiths |
| 2 | Adam | Smith |
| 3 | George | Kowalsky |
| 4 | George | Kowalsky |
| 5 | Susan | Connor |
| 6 | Clare | Connory |
| 7 | Susan | Connor |
And for ['Smith', 'Connor'] the output is:
| Id | Name | Surname |
|----|-------|---------|
| 1 | John | Smiths |
| 5 | Susan | Connor |
In Postgres you can use the ANY operator to compare a single value to all values of an array. This also works with together with the LIKE operator.
SELECT *
FROM "Users"
WHERE "Surname" like ANY (array['Smith%', 'Connor%'])
Note that LIKE is case sensitive, if you don't want that, you can use ILIKE
This will show you the logic. Syntax is up to you.
where 1 = 2
start of loop
or surname like 'Array Element goes here%'
end of loop

ORDER BY FIELD LIST - Subquery returns more than 1 row

What i want to do is quite simple:
Write an SQL that will return a bunch of record and order the records by some list of id from the FIELD LIST section of my SQL
TABLE SAMPLE
lessons
+----+----------------------+
| id | name |
+----+----------------------+
| 9 | Greedy algorithms |
| 5 | Maya civilization |
| 3 | eFront Beginner |
| 2 | eFront Intermediate |
+----+----------------------+
mod_comp_rule
+----+---------------------+
| id | lesson_id | comp_id |
+----+---------------------+
| 1 | 3 | 1 |
| 2 | 2 | 1 |
| 3 | 9 | 2 |
+----+---------------------+
WHAT I WANT TO GET FROM MY QUERY
SELECT * FROM lessons ORDER BY FIELD(id,'3','2','9') ASC;
MY SQL
SELECT ls.id, ls.name
FROM lessons ls
ORDER BY FIELD(ls.id,
(SELECT mcr.lesson_id FROM mod_comp_rule mcr
INNER JOIN lessons ls ON ls.id = mcr.lesson_id))
My SQL Query returned the following error
MySQL said: #1242 - Subquery returns more than 1 row
So how can i make my SQL return FIELD(id,'3','2','9') without flagging the more than 1 row error ?
I don't see why FIELD() is needed for this. A correlated query will do what you want:
SELECT ls.id, ls.name
FROM lessons ls
ORDER BY (SELECT mcr.id FROM mod_comp_rule mcr WHERE ls.id = mcr.lesson_id);

SQLite . Add the values in two columns and output in another column without showing the two columns

I have a table with information like this.
ID | Name | #ofCow | UItem | place
--------+---------+-------- +---------+----------
0 | Bob | 7 | 1 | maine
1 | Bob | 3 | 5 | new york
2 | Tom | 2 | 5 | cali
I wish to produce a table like this where it would add up the number of cows and Uitem if the name is the same. However my select query seems to not be working. I suspect it is because the place column is the problem. Since you can't add 'Maine' and 'New York' together. Can anyone help me find a solution ?
ID | Name | #ofCow | UItem |
--------+---------+-------- +---------+
0 | Bob | 10 | 6 |
2 | Tom | 2 | 5 |
TLDR : Add the values in two columns in table 1 if name is same. Output in another column. Don't show the two columns. I don't need places also.
You could use this (I have considered the name of the table as HolyCow) :
SELECT holy.ID,
holy.Name,
SUM(holy.Cows) as '#ofCow',
SUM(holy.UItem) as 'UItem'
FROM HolyCow holy
GROUP BY holy.ID, holy.Name
ORDER BY holy.Name
Hope this helps!!

Codeigniter - get related entries

I have two tables, one that store some data like name, sex etc. end the seconds that store images related from the id of the first table.
I need to get the row of the first table and get also all the images from the second one and I would like to get them with a single query.
How can I do that? is it possibile?
I have tried with a simple join but I get just the first element of the second table.
Example Table 1:
----------------------
|ID | Name | Sex |
----------------------
| 1 | Chris | Male |
----------------------
| 2 | Elisa | Female |
----------------------
Table 2:
------------------------------
| ID | User_id | Image name |
------------------------------
| 1 | 1 | img1.jpg |
------------------------------
| 2 | 1 | img2.jpg |
------------------------------
| 3 | 1 | img3.jpg |
------------------------------
| 4 | 2 | img4.jpg |
------------------------------
I would like to have:
Chris, Male, img1.jpg, img2.jpg, img3.jpg
Elisa, Female, img4.jpg
And so on...any advice?
SELECT
table1.*,
GROUP_CONCAT(table2.image_name SEPARATOR ', ') as image_name
FROM table1
LEFT JOIN table2
ON table1.id = table2.user_id
GROUP BY table1.id;
Demo : SQL Fiddle
Try with a left outer join
SELECT user.*, image.image_name as image
FROM user
LEFT OUTER JOIN image
ON user.id = image.user_id
It will get all the user rows and put empty val in image if none was found.