Codeigniter - get related entries - sql

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.

Related

How to select table with a concatenated column?

I have the following data:
select * from art_skills_table;
+----+------+---------------------------+
| ID | Name | skills |
+----+------+---------------------------|
| 1 | Anna | ["painting","photography"]|
| 2 | Bob | ["drawing","sculpting"] |
| 3 | Cat | ["pastel"] |
+----+------+---------------------------+
select * from computer_table;
+------+------+-------------------------+
| ID | Name | skills |
+------+------+-------------------------+
| 1 | Anna | ["word","typing"] |
| 2 | Cat | ["code","editing"] |
| 3 | Bob | ["excel","code"] |
+------+------+-------------------------+
I would like to write an SQL statement which results in the following table.
+------+------+-----------------------------------------------+
| ID | Name | skills |
+------+------+-----------------------------------------------+
| 1 | Anna | ["painting","photography","word","typing"] |
| 2 | Bob | ["drawing","sculpting","excel","code"] |
| 3 | Cat | ["pastel","code","editing"] |
+------+------+-----------------------------------------------+
I've tried something like SELECT * from art_skills_table LEFT JOIN computer_table ON name. However it doesn't give what I need. I've read about array_cat but I'm having a bit of trouble implementing it.
if the skills column from both tables are arrays, then you should be able to get away with this:
SELECT a.ID, a.name, array_cat(a.skills, c.skills)
FROM art_skills_table a LEFT JOIN computer_table c
ON c.id = a.id
That said, While you used LEFT join in your sample, I think either an INNER or FULL (OUTER) join might serve you better.
First, i wondered why the data are stored in such a model.
Was of the opinion that NoSQL databases lack ability for joins and ...
... a semantic triple would be in the form of subject–predicate–object.
... a Key-value (KV) stores use associative arrays.
... a relational database would be normalized.
A few information about the use case would have helped.
Nevertheless, you can select the data with CONCAT and REPLACE for the desired form.
SELECT art_skills_table.ID, computer_table.name,
CONCAT(
REPLACE(art_skills_table.skills, '}',','),
REPLACE(computer_table.skills, '{','')
)
FROM art_skills_table JOIN computer_table ON art_skills_table.ID = computer_table.ID
The query returns the following result:
+----+------+--------------------------------------------+
| ID | Name | Skills |
+----+------+--------------------------------------------+
| 1 | Anna | {"painting","photography","word","typing"} |
| 2 | Cat | {"drawing","sculpting","code","editing"} |
| 3 | Bob | {"pastel","excel","code"} |
+----+------+--------------------------------------------+
I've used the ID for the JOIN, even though Bob has different values.
The JOIN should probably be done over the name.
JOIN computer_table ON art_skills_table.Name = computer_table.Name
BTW, you need to tell us what SQL engine you're running on.

SQL conditional join with default values

I'm kinda struggling with this query, I have the following table:
setting
-------
id | name | value | type
--------------------------------
1 | title | Hi | string
2 | color | #ff0000 | string
user_setting
-------
id | userId | settingId | value
--------------------------------
1 | 1 | 1 | Hello
user
-------
id | email
1 | foo#test.com
I want to run a query that will select all settings for user 1, but also include the default value, so ideally I get this:
id | default | value
-----------------------
title | Hi | Hello
color | #ff0000 | null
My current query is
SELECT setting.id, setting.name, setting.value, user_setting.value, user.id
FROM setting
RIGHT JOIN user_setting
ON setting.id = "user_setting"."settingId"
LEFT OUTER JOIN user
ON "user_setting"."userId" = user.id
WHERE user.id = 1
But this only gives me the values that the user has defined.
EDIT: Updated setting table
I think you want a left join. But I think your setting is missing a column for setting_id (or whatever it is called). So the table should really be:
setting
-------
id | name | value | type
--------------------------------
1 | title | Hi | string
2 | color | #ff0000 | string
Otherwise user_settings.setting_id doesn't refer to anything. With this column, you want:
select s.name, s.value as default, us.value
from setting s left join
user_setting us
on us.setting_id = s.id and us.user_id = 1

BigQuery Match Table Lookup for DCM Data Transfer

With DCM's Data Transfer v2 you get 3 main tables of data in GCS:
p_activity_166401
p_click_166401
p_impression_166401
Along with a plethora of match tables like:
p_match_table_advertisers_166401
p_match_table_campaigns_166401
Table 1: p_activity_166401
Row | Event_time | User_ID | Advertiser_ID | Campaign_ID |
------ | ------------- | ------- | ------------- | ----------- |
1 | 149423090566 | AMsySZa | 5487307 | 9638421 |
2 | 149424804284 | 2vmdsXS | 5487307 | 10498283 |
Table 2: p_match_table_advertisers_166401
Row | Advertiser_ID | Advertiser |
------ | ------------- | ----------- |
1 | 5487307 | Company A |
2 | 5487457 | Company B |
How do I reference a value from Table 1 in Table 2 and return the value from Table 2 in a query?
I'd like a result like:
Row | Advertiser | User_ID |
------ | ---------- | ----------- |
1 | Company A | AMsySZa |
2 | Company A | 2vmdsXS |
Been searching around here and online and I just can't seem to find a clear reference on how to do the lookups across table, apologies in advance is this is a really simple thing I'm missing :)
EDIT
So with a nudge in the right direction I have found the JOIN function...
SELECT
*
FROM
[dtftv2_sprt.p_activity_166401]
INNER JOIN
[dtftv2_sprt.p_match_table_advertisers_166401]
ON
[p_activity_166401.Advertiser_ID] =
p_match_table_advertisers_166401.Advertiser_ID]
LIMIT
100;
Error: Field 'p_activity_166401.Advertiser_ID' not found.
That is definitely a field in the table.
So this query works great in creating a view with all the data in it.
SELECT
*
FROM
[dtftv2_sprt.p_activity_166401]
INNER JOIN
[dtftv2_sprt.p_match_table_advertisers_166401]
ON
dtftv2_sprt.p_activity_166401.Advertiser_ID = dtftv2_sprt.p_match_table_advertisers_166401.Advertiser_ID;
Using the view I can now run smaller queries to pull the data I want out. Thanks for guiding me in the right direction Mikhail Berlyant.

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

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.

PostgreSQL Inner Join on the same table + second table?

If this is a stupid question, forgive me, I'm not very familiar with PostgreSQL.
I've collected inventory data from used car dealerships in my area and stored it in a postgreSQL table. I've got a second table with particular details regarding certain makes and models. For example:
The dealership table is structured like so:
-----------------------------------------
| Dealership | Make | Model | Year | ID |
----------------------------------------|
| A | Ford | F250 | 2003 | 1 |
| A | Chevy| Cobalt| 2005 | 2 |
| B | Ford | F250 | 2003 | 1 |
| B | Dodge| Chrgr | 2012 | 3 |
-----------------------------------------
The details table is structured like so:
-----------------------------------------
| ID | DetailA| DetailB| DetailC|
-----------------------------------------
| 1 | data | data | data |
| 2 | data | data | data |
| 3 | data | data | data |
| 4 | data | data | data |
-----------------------------------------
My goal is to retrieve vehicle matches from multiple dealerships and display the appropriate details. In the above example, I would like to see:
-----------------------------------------------------
| Make | Model | Year | DetailA | DetailB | DetailC |
-----------------------------------------------------
| Ford | F250 | 2003 | data | data | data |
-----------------------------------------------------
With this result, I will know that both A and B havea 2003 Ford F250 for sale, and can view the related details of the vehicle.
I've tried many different queries, but most are variations on something like this:
SELECT DISTINCT
dealership_table.make,
dealership_table.model,
dealership_table.year
details_table.detaila,
details_table.detailb,
details_table.detailc
FROM
dealership_table
INNER JOIN
details_table
ON
dealership_table.id = details_table.id
WHERE
dealership_table.dealership = 'A'
OR
dealership_table.dealership = 'B'
However this returns all of the distinct matches from the table where dealership is either A or B. I've tried multiple inner-joins, but I an error complaining details_table is specified multiple times.
If I'm doing something really silly, I apologize. Like I said before, I'm pretty much an SQL noob.
What am I doing wrong? How should I go about retrieving the desired results? Any suggestions, solutions, or advice is greatly appreciated!
You can write:
SELECT dealership_table1.make,
dealership_table1.model,
dealership_table1.year,
details_table.detaila,
details_table.detailb,
details_table.detailc
FROM dealership_table dealership_table1
JOIN dealership_table dealership_table2
ON dealership_table1.make = dealership_table2.make
AND dealership_table1.model = dealership_table2.model
AND dealership_table1.year = dealership_table2.year
JOIN details_table
ON dealership_table.id = details_table.id
WHERE dealership_table1.dealership = 'A'
AND dealership_table1.dealership = 'B'
;
(Note that the FROM dealership_table dealership_table1 and JOIN dealership_table dealership_table2 set up distinct "aliases", so you can use the same table multiple different times in the same query without getting name-conflicts.)
I may be misunderstanding your table layout, but I think you should consider changing to a different structure. Here's what I would propose:
Vehicle:
----------------------------
| ID | Make | Model | Year |
----------------------------
| 1 | Ford | F250 | 2003 |
| 2 | Chevy| Cobalt| 2005 |
| 3 | Dodge| Chrgr | 2012 |
----------------------------
Dealership:
----------------------------
| Dealership | ID | Detail |
----------------------------
| A | 1 | data |
| A | 2 | data |
| B | 1 | data |
| B | 3 | data |
----------------------------
This way you're not storing vehicle information (make/model/year) in more than one place.
Here's how you would write your desired query given the above schema:
SELECT Make, Model, Year, A.Detail, B.Detail, C.Detail
FROM Vehicle V
LEFT OUTER JOIN Dealership A on A.Dealership = 'A' and A.id = V.id
LEFT OUTER JOIN Dealership B on B.Dealership = 'B' and B.id = V.id
LEFT OUTER JOIN Dealership C on C.Dealership = 'C' and C.id = V.id