PostgreSQL: How to add Column from other table in select statement? - sql

I'm trying to select a column from another table like I used to do in MSSQL:
select * , Date = (select top 1 Date from [dbo].TableB where status = 1 order by Date desc)
from [dbo].TableA
How can I do that in PostgreSQL?
Additional sample data:
TableA
Names
Richards
Marcos
Luke
Matthew
John
TableB
Date Status
2016-01-01 1
2016-01-02 0
2016-01-03 1
2016-01-04 1
2016-01-05 1
Expected Output:
Name Date
Richards 2016-01-02
Marcos 2016-01-02
Luke 2016-01-02
Matthew 2016-01-02
John 2016-01-02
Thanks!

Date = (...) is invalid (standard) SQL and won't work in Postgres (or any other DBMS except for SQL Server)
A column alias is defined using AS ... in SQL (and Postgres). Postgres also doesn't have top. It uses limit.
Using square brackets in an identifier is also not allowed in SQL. So [dbo] needs to become dbo or "dbo" depending on how you created the schema.
select a.*,
(select date
from dbo.tableb as b
where b.status = 1
order by b.date desc
limit 1) as date
from dbo.tablea a
date is a reserved word and should not be used as an identifier (column name)
If you want to use standard ANSI SQL, you can also use fetch first 1 row only instead of limit 1.
Another option would be to use max() instead of the limit in the sub-select which doesn't need the limit at all:
select a.*,
(select max(date)
from dbo.tableb as b
where b.status = 1) as date
from dbo.tablea a

I'm not sure if this is the correct syntax, but did you try this:
select * , (select NewColumn from [dbo].TableB) as NewColumn
from [dbo].TableA
I hope it helps.

I'm not too familiar with PostgreSQL but SQL is still SQL.
First thing to say is you have to have only one result on the second table query and you can do it in
SELECT
A.*
(select NewColumn from [dbo].TableB.NewColumn) as NewColumn
FROM TableA
However I think you'll need to declare a join condition.
SELECT
A.*
(select NewColumn from [dbo].TableB.NewColumn where A.Col1 = TableB.col1)
FROM TableA A
without a real example I cant be more specific.

Try this:
select a.*, b.column
from tableA as a, tableB as b;

You could try doing a CROSS JOIN:
SELECT * FROM
(SELECT * FROM dbo.TableA),
(SELECT Date FROM dbo.TableB WHERE status = 1 ORDER BY Date DESC LIMIT 1)

Related

How to Insert values into datatable from another datatable SQL

I have table1 with the following data :
ID
Name
Date
1
Paul
01-11-2020
1
Paul
03-11-2020
and have table2 only with a Date column:
Date
02-11-2020
I want to get output from those tables as:
ID
Name
Date
1
Paul
01-11-2020
1
Paul
02-11-2020
1
Paul
03-11-2020
Could someone help me how to join two tables to get the output like above. I tried so many ways but I couldn't solve this issue. Thank you...
You can use CROSS JOIN after applying UNION ALL in order to return from the both tables in a row-wise manner such as
SELECT DISTINCT COALESCE(tt.ID,t1.ID) AS ID,
COALESCE(tt.Name,t1.Name) AS Name, tt.Date
FROM table1 AS t1
CROSS JOIN (SELECT * FROM table1 UNION ALL
SELECT null,null,Date FROM table2) AS tt
ORDER BY 3
Demo

Bigquery: WHERE clause using column from outside the subquery

New to Bigquery, and googling could not really point me to the solution of the problem.
I am trying to use a where clause in a subquery to filter and pick the latest row for each other row in the main query. In postgres I'd normally do it like this:
SELECT
*
FROM
table_a AS a
LEFT JOIN LATERAL
(
SELECT
score,
CONCAT( "AB", id ) AS id
FROM
table_b AS b
WHERE
id = a.company_id
and
b.date < a.date
ORDER BY
b.date DESC
LIMIT
1
) ON true
WHERE
id LIKE 'AB%'
ORDER BY
createdAt DESC
so this would essentially run the subquery against each row and pick the latest row from table B based on a given row's date from table A.
So if table A would have a row
id
date
12
2021-05-XX
and table B:
id
date
value
12
2022-01-XX
99
12
2021-02-XX
98
12
2020-03-XX
97
12
2019-04-XX
96
It would have joined only the row with 2021-02-XX to table a.
In another example, with
Table A:
id
date
15
2021-01-XX
Table B:
id
date
value
15
2022-01-XX
99
15
2021-02-XX
98
15
2020-03-XX
97
15
2019-04-XX
96
it would join only the row with date: 2020-03-XX, value: 97.
Hope that is clear, not really sure how to write this query to work
Thanks for help!
You can replace some of your correlated sub-select logic with a simple join and qualify statement.
Try the following:
SELECT *
FROM table_a a
LEFT JOIN table_b b
ON a.id = b.id
WHERE b.date < a.date
QUALIFY ROW_NUMBER() OVER (PARTITION BY b.id ORDER BY b.date desc) = 1
With your sample data it produces:
This should work for both truncated dates (YYYY-MM) as well as full dates (YYYY-MM-DD)
Something like below should work for your requirements
WITH
latest_record AS (
SELECT
a.id,
value,b.date, a.createdAt
FROM
`gcp-project-name.data-set-name.A` AS a
JOIN
`gcp-project-name.data-set-name.B` b
ON
( a.id = b.id
AND b.date < a.updatedAt )
ORDER BY
b.date DESC
LIMIT
1 )
SELECT
*
FROM
latest_record
I ran this with table A as
and table B as
and get result

Remove duplicates in Select query based on one column

I want to select without duplicate ids and keep row '5d' and not '5e' in select statement.
table
id | name
1 | a
2 | b
3 | c
5 | d
5 | e
I tried:
SELECT id, name
FROM table t
INNER JOIN (SELECT DISTINCT id FROM table) t2 ON t.id = t2.id
For the given example an aggregation using min() would work.
SELECT id,
min(name) name
FROM table
GROUP BY id;
You can also use ROW_NUMBER():
SELECT id, name
FROM (
SELECT id, name, ROW_NUMBER() OVER(PARTITION BY id ORDER BY name) rn
FROM mytable
) x
WHERE rn = 1
This will retain the record that has the smallest name (so '5d' will come before '5e'). With this technique, you can also use a sort criteria on another column that the one where duplicates exists (which an aggregate query with MIN() cannot do). Also, queries using window functions usually perform better than the equivalent aggregate query.
If you want to keep the row with the smallest name then you can use not exists:
select t.* from tablename t
where not exists (
select 1 from tablename
where id = t.id and name < t.name
)

Better solution for existing sql query

I have table like this:
type | date | id
-----------------------------
1 | 2012-01-01 | 1
2 | 2012-01-01 | 2
1 | 2012-02-02 | 3
2 | 2012-02-02 | 4
I need to build query that will pick all "up-to-date" distinct values of type ( in this example it will be records with id's 3 and 4). Now i have this solution :
select * from test t1 where date =
(select max(date) from test t2 where t2.type = t1.type ) order by type, date desc
I am embarrassed by the presence of nested select, maybe there is more elegant solution ?
since you didn't mention the RDBMS you are using, try this one. will work on most RDBMS.
SELECT a.*
FROM tableName a
INNER JOIN
(
SELECT type, MAX(DATE) maxDAte
FROM tableName
GROUP BY type
) b ON a.type = b.type AND
a.DATE = b.maxDate
SQLFiddle Demo
or if you RDBMS supports Window Function
SELECT type, date, id
FROM
(
SELECT type, date, id,
ROW_NUMBER() OVER (PARTITION BY type
ORDER BY date DESC) rn
FROM tableNAme
) s
WHERE rn = 1
SQLFiddle Demo
In your particular example, this could work also:
select type, max(date), max(id)
from your_table
group by type
but notice that it will work only if you are absolutely sure that dates and ids are always increasing. If this is not the case, max(date) and max(id) could be on two different rows. Use this only if you know what you are doing! If not, there's nothing wrong with nested queries.

How do I select all the columns from a table, plus additional columns like ROWNUM?

In Oracle, it's possible to do a SELECT statement that returns the row number as a column in your result set.
For example,
SELECT rownum, column1, column2 FROM table
returns:
rownum column1 column2
1 Joe Smith
2 Bob Jones
But I don't want to specify each column by hand. I want to do something like:
select rownum,* from table
rownum column1 column2 column3 column4
1 Joe Smith 1 2
2 Bob Jones 3 4
Any ideas?
Qualify the * with the name of the table:
select rownum, table.* from table
Dave's answer is great, i'd just like to add that it's also possible to do that by placing the wildcard as the first column:
select *,rownum from table
Works, but the following won't:
select rownum,* from table
I've tested on MySQL.
Dave's answer did not work for me on Oracle 11g (table.* without alias). The following worked:
select rownum, t.* from table t
Unfortuantely, i dont think therei s a way to do it, easiest is probably inner join with itself with an inline table of id,count(*), and put an outer select statement