How to select distinct-columns along with one nondistinct-column in DB2? - select

I need to perform distinct select on few columns out of which, one column is non-distinct. Can I specify which columns make up the distinct group in my SQL statement.
Currently I am doing this.
Select distinct a,b,c,d from TABLE_1 inner join TABLE_2 on TABLE_1.a = TABLE_2.a where TABLE_2.d IS NOT NULL;
The problem I have is I am getting 2 rows for the above SQL because column D holds different values. How can I form a distinct group of columns (a,b&c) ignoring column d, but have column d in my select clause as well?
FYI: I am using DB2
Thanks
Sandeep

SELECT a,b,c,MAX(d)
FROM table_1
INNER JOIN table_2 ON table_1.a = table_2.a
GROUP BY a,b,c

Well, your question, even with refinements, is still pretty general. So, you get a general answer.
Without knowing more about your table structure or your desired results, it may be impossible to give a meaningful answer, but here goes:
SELECT a, b, c, d
FROM table_1 as t1
JOIN table_2 as t2
ON t2.a = t1.a
AND t2.[some_timestamp_column] = (SELECT MAX(t3.[some_timestamp_column])
FROM table_2 as t3
WHERE t3.a = t2.a)
This assumes that table_1 is populated with single rows to retrieve, and that the one-to-many relationship between table_1 and table_2 is created because of different values of d, populated at unique [some_timestamp_column] times. If this is the case, it will get the most-recent table_2 record that matches to table_1.

Related

Get an Empty Column from a table when filter condition fetches empty in PostgreSQL

I have two tables table1(id,name,type) and table2(id,source,destination)
When I run query
SELECT
name,
source,
destination
FROM
table1,
table2
WHERE
table1.id=table2.id
If there's no id matching between two tables, can I still get empty column for source and destination .
Yes, you basically want an OUTER JOIN and remember to always use the explicit ANSI JOIN syntax and not the implicit comma syntax for joins.Also use proper table aliases to avoid ambiguity.
SELECT
t1.name,
t2.source,
t2.destination
FROM
table1 t1 left outer join
table2 t2 ON t1.id = t2.id

Select from view and join from one table or another if no record available in first

I have a view and two tables. Tables one and two have the same columns, but table one is has as small number of records, and table two has old data and a huge number of records.
I have to join a view with these two tables to get the latest data from table one; if a record from the view is not available in table one then I have to select the record from table two.
How can i achieve this with MySQL?
I came to know by doing some research in internet that we can't apply full join and sub query in from clause.
Just do a simple UNION of the results excluding the records in table2 that are already mentioned in table1:
SELECT * FROM table1
UNION
SELECT * FROM table2
WHERE NOT EXISTS (SELECT * FROM table1 WHERE table2.id = table1.id)
Something like this.
SELECT *
FROM view1 V
INNER JOIN (SELECT COALESCE(a.commoncol, b.commoncol) AS commoncol
FROM table1 A
FULL OUTER JOIN table2 B
ON A.commoncol = B.commoncol) C
ON v.viewcol = c.commoncol
If you are using Mysql then check here to simulate Full Outer Join in MySQL
are you trying to update the view from two tables where old record in view needs to be overwritten by latest/updated record from table1 and non existant records from table1 to be appended from table2?
, or are you creating a view from two tables?

Select distinct join in HQL Request

I have a bit complicated request to do in HQL and I don't manage to obtain the result I want.
Here is what I want to do :
I have two entities t1 and t2 with a OneToMany relation between both.
I want to select some infos from both tables in the same request but here is the issue, I don't want any duplicate of t1.
So basically I want 4 properties, 3 from t1 and 1 from t2, but as there are several records from t2 for the same t1 object, I just want to get the first from t2 to not have any t1 duplicated records.
Here is what I did :
SELECT DISTINCT(t1.a , t1.b, t1.c, t2.z) FROM t1 LEFT JOIN t2
But Obviously, that worked when I did not need any t2 parameter, but now I have some records (a,b,c) duplicated for different t2.z
And I don't find any way in HQL to do it (I can't do any Select LIMIT 1 that could work in SQL).
Does anybody have an idea on how to resolve that?
Thanks

Postgres: left join with order by and limit 1

I have the situation:
Table1 has a list of companies.
Table2 has a list of addresses.
Table3 is a N relationship of Table1 and Table2, with fields 'begin' and 'end'.
Because companies may move over time, a LEFT JOIN among them results in multiple records for each company.
begin and end fields are never NULL. The solution to find the latest address is use a ORDER BY being DESC, and to remove older addresses is a LIMIT 1.
That works fine if the query can bring only 1 company. But I need a query that brings all Table1 records, joined with their current Table2 addresses. Therefore, the removal of outdated data must be done (AFAIK) in LEFT JOIN's ON clause.
Any idea how I can build the clause to not create duplicated Table1 companies and bring latest address?
Use a dependent subquery with max() function in a join condition.
Something like in this example:
SELECT *
FROM companies c
LEFT JOIN relationship r
ON c.company_id = r.company_id
AND r."begin" = (
SELECT max("begin")
FROM relationship r1
WHERE c.company_id = r1.company_id
)
INNER JOIN addresses a
ON a.address_id = r.address_id
demo: http://sqlfiddle.com/#!15/f80c6/2
Since PostgreSQL 9.3 there is JOIN LATERAL (https://www.postgresql.org/docs/9.4/queries-table-expressions.html) that allows to make a sub-query to join, so it solves your issue in an elegant way:
SELECT * FROM companies c
JOIN LATERAL (
SELECT * FROM relationship r
WHERE c.company_id = r.company_id
ORDER BY r."begin" DESC LIMIT 1
) r ON TRUE
JOIN addresses a ON a.address_id = r.address_id
The disadvantage of this approach is the indexes of the tables inside LATERAL do not work outside.
I managed to solve it using Windows Function:
WITH ranked_relationship AS(
SELECT
*
,row_number() OVER (PARTITION BY fk_company ORDER BY dt_start DESC) as dt_last_addr
FROM relationship
)
SELECT
company.*
address.*,
dt_last_addr as dt_relationship
FROM
company
LEFT JOIN ranked_relationship as relationship
ON relationship.fk_company = company.pk_company AND dt_last_addr = 1
LEFT JOIN address ON address.pk_address = relationship.fk_address
row_number() creates an int counter for each record, inside each window based to fk_company. For each window, the record with latest date comes first with rank 1, then dt_last_addr = 1 makes sure the JOIN happens only once for each fk_company, with the record with latest address.
Window Functions are very powerful and few ppl use them, they avoid many complex joins and subqueries!

Calculating correlation coefficient using PostgreSQL?

I have worked out how to calculate the correlation coefficient between two fields if both are in the same table:
SELECT corr(column1, column2) FROM table WHERE <my filters>;
...but I can't work out how to do it when the columns are from different tables (I need to apply the same filters to both tables).
Any hints, please?
If the tables are related to one another such that you can join them, it's fairly simple. Just join them and do the correlation:
SELECT corr(t1.col1, t2.col2)
FROM table1 t1
JOIN table2 t2
ON t1.join_field = t2.join_field
WHERE
<filters for t1>
AND
<filters for t2>
If they're not, then how are you supposed to find out which combination of fields from each table you want to run corr on?
try this
SELECT corr(t1.column1, t2.column2)
FROM table1 t1
join table2 t2 on t1.SomeColumn = t2.SomeColumn
WHERE t1.<my filters>
AND t2.<my filters>;