I'm using node-postgres to return a joined table to the front end of my React app through an express server. Here is the query...
SELECT channels.name as channels, programmes.title as title, series.number as series, episodes.episode_number as episode
FROM programmes
INNER JOIN programme_channels ON programme_channels.programme_id = programmes.programme_id
INNER JOIN channels ON programme_channels.channel_id = channels.channel_id
INNER JOIN series ON programmes.programme_id = series.programme_id
INNER JOIN episodes ON series.series_id = episodes.series_id
This works as needed, however I'd like for front-end users to be able to update or delete columns of the table. To do this, each cell of my table would need to know the origin of its data. Currently the query I have returns a table like this...
channel | title | series | episode
--------------+------------+---------------+---------
Some Channel | Some title | 1 | 1
Where channel is from the channels, title, series and episode are all from different tables. For a user to update or delete this data, they will need the origins of each column for the query.
The node-postgres query returns some more information which may be helpful for this in the form of a fields array...
fields: [
Field {
name: 'title',
tableID: 16554,
columnID: 2,
dataTypeID: 1043,
dataTypeSize: -1,
dataTypeModifier: 104,
format: 'text'
},
...]
and I can return a table with the original table name of a column using this query...
SELECT relname
FROM pg_catalog.pg_statio_user_tables
WHERE relid = '16554'
result...
relname
----------
programmes
however I'm not sure how to use the results of this to query the table 'programmes'. This is where I've hit a wall. My questions are...
Am I going about this the right way, or is there an easier way to update data returned from a joined table?
If so, is there any way I can SELECT a table by either the relid or the result of a query.
Say I have this json in a SQL Column called MyJson in a table called StoreTeams
{
MyTeams: [
{
id: 1
},
{
id: 2
},
{
id: 3
}
]
}
I want to take all these id's and then do a inner join against another table.
User Table
- id <pk>
- firstName
- lastName
I am not sure how I would do this, I would be probably running this code via ado.net.
You can use openjson(). You don't specify the exact result you want, but the logic is:
select *
from mytable t
cross apply openjson(t.myjson, '$.MyTeams') with (id int '$.id') as x
inner join users u on u.id = x.id
I want to extract data for a list of userid I am interested in. If the list is short, I can type the query directly:
SELECT * FROM mytable WHERE userid IN (100, 101, 102);
(this is an example, the query might be more complex). But the list of userid might be long and available as a text file:
100
101
102
How can I run the same query with Hive reading from userids.txt directly?
One way is to put the data in another table and INNER JOIN to it, so that there has to be a match for the record to go through:
Create the table: CREATE TABLE users (userid INT);
Load the data file: LOAD DATA LOCAL INPATH 'userids.txt' INTO TABLE users;
Filter through the inner join: SELECT mytable.* FROM mytable INNER JOIN users ON mytable.userid = users.userid;
Let's say I create two tables using the following SQL,
such that post has many comment:
CREATE TABLE IF NOT EXISTS post (
id SERIAL PRIMARY KEY,
title VARCHAR NOT NULL,
text VARCHAR NOT NULL
)
CREATE TABLE IF NOT EXISTS comment (
id SERIAL PRIMARY KEY,
text VARCHAR NOT NULL,
post_id SERIAL REFERENCES post (id)
)
I would like to be able to query these tables so as to serve a response that
looks like this:
{
"post" : [
{ id: 100,
title: "foo",
text: "foo foo",
comment: [1000,1001,1002] },
{ id: 101,
title: "bar",
text: "bar bar",
comment: [1003] }
],
"comment": [
{ id: 1000,
text: "bla blah foo",
post: 100 },
{ id: 1001,
text: "bla foo foo",
post: 100 },
{ id: 1002,
text: "foo foo foo",
post: 100 },
{ id: 1003,
text: "bla blah bar",
post: 101 },
]
}
Doing this naively would involve to SELECT statements,
the first along the lines of
SELECT DISTINCT ON(post.id), post.title, post.text, comment.id
FROM post, comment
WHERE post.id = comment.post_id
... and the second something along the lines of
SELECT DISTINCT ON(comment.id), comment.text, post.id
FROM post, comment
WHERE post.id = comment.post_id
However, I cannot help but think that there is a way to do this involving
only one SELECT statement - is this possible?
Notes:
I am using Postgres, but I do not require a Postgres-specific solution. Any standard SQL solution should do.
The queries above are illustrative only, they do not give we exactly what is necessary at the moment.
It looks like what the naive solution here does is perform the same join on the same two tables, just doing a distinct on a different table each time. This definitely leaves room for improvement.
It appears that ActiveModel Serializers in Rails already do this - if someone familair with them would like to chime in how they work under the hood, that would be great.
You need two queries to get the form you laid out:
SELECT p.id, p.title, p.text, array_agg(c.id) AS comments
FROM post p
JOIN comment c ON c.post_id = p.id
WHERE p.id = ???
GROUP BY p.id;
Or faster, if you really want to retrieve all or most of your posts:
SELECT p.id, p.title, p.text, c.comments
FROM post p
JOIN (
SELECT post_id, array_agg(c.id) AS comments
FROM comment
GROUP BY 1
) c ON c.post_id = p.id
GROUP BY 1;
Plus:
SELECT id, text, post_id
FROM comment
WHERE post_id = ??;
Single query
SQL can only send one result type per query. For a single query, you would have to combine both tables, listing columns for post redundantly. That conflicts with the desired response in your question. You have to give up one of the two conflicting requirements.
SELECT p.id, p.title, p.text AS p_text, c.id, c.text AS c_text
FROM post p
JOIN comment c ON c.post_id = p.id
WHERE p.id = ???
Aside: The column comment.post_id should be integer, not serial! Also, column names are probably just for a quick show case. You wouldn't use the non-descriptive text as column name, which also conflicts with a basic data type.
Compare this related case:
Foreign key of serial type - ensure always populated manually
However, I cannot help but think that there is a way to do this involving only one SELECT statement - is this possible?
Technically: yes. If you really want your data in json anyway, you could use PostgreSQL (9.2+) to generate it with the json functions, like:
SELECT row_to_json(sq)
FROM (
SELECT array_to_json(ARRAY(
SELECT row_to_json(p)
FROM (
SELECT *, ARRAY(SELECT id FROM comment WHERE post_id = post.id) AS comment
FROM post
) AS p
)) AS post,
array_to_json(ARRAY(
SELECT row_to_json(comment)
FROM comment
)) AS comment
) sq;
But I'm not sure it's worth it -- usually not a good idea to dump all your data without limit / pagination.
SQLFiddle
I am very new to SQL.
I have two tables to merge, the following code works
SELECT *
FROM confirm
JOIN order ON confirm.email = order.email
But this one does not work for me
SELECT *
FROM confirm
JOIN order ON confirm.custid = order.custid
Everything here (email, custid) is VARCHAR(22). For the first one I get expected results but no matching results for the second one. The email and custid records are variable length between records. I also tried trim()- not avail. Any pointers?
AND custid is in the following format AB12345
-two letters and numbers
As Jeremy stated in his comment, if the "custid" does not match exactly, it will not join.
Example:
Table 1:
Email : abc#abc.com
CustId : AB12345
Email: abc2#abc.com
CustId : AB12346
Table 2:
Email: abc#abc.com
CustId : AB12345
Email: abc3#abc.com
CustId : AB12347
If you do:
SELECT * FROM TableA A
INNER JOIN TableB B on B.CustId = A.CustId
Your result will be:
Email: abc#abc.com and CustId: AB12345
This is because those columns match each other. abc2 and abc3 do not match in both tables, so they will not appear in the results.
You first go through both table check whether any matching custid is there or not,if there apply some where condition and filter it out,like select * from tblconfirm where custid="AB1234",like that chck in the case of other table,if it is there then no problem ,else no result will come.