Join based on min - sql

I have two tables.
Table1:
id, date
Table2:
id,date
Both the table contain information about id. Table1 and Table2 can have some extra rows which are not present in another table.
Example:
Table1:
1,15-Jun
2,16-Jun
4,17-Jun
Table2
1,14-Jun
2,17-Jun
3,18-Jun
I need a summarize result which give minimum date for each row.
Expected result:
1,14-Jun
2,16-Jun
3,18-Jun
4,17-Jun

select id, min(date_) from (
select id, date_ from table1
union all
select id, date_ from table12
) group by id;

SELECT id, MIN(date)
FROM (SELECT id, date
FROM Table1
UNION
SELECT id, date
FROM Table2)
GROUP BY id

with a as(select t.i_id,t.dt_date from t
union
select b.i_id,b.dt_date from b)
select a.i_id,min(a.dt_date) from a group by a.i_id order by a.i_id;
You can check this link

Related

PostgreSQL query to list all values of a column that are common between tables

I have a column named endate(its values are dates) present in five tables, straddle0, straddle1, straddle2, straddle3 and straddle4. My assumption regarding the data is that, one table's endate values are not present in any of the other mentioned tables(can be repeated in the same table though). But to confirm, I want to list all the endate values that might be present in multiple tables (like 01-01-2017 is present in straddle0 and also in straddle4 or 02-02-2017 is present in straddle1 and also in straddle3 and straddle5).
What is the PostgreSQL query for the same?
I would use UNION ALL and a GROUP BY/HAVING:
Schema (PostgreSQL v13)
CREATE TABLE t1 (
enddate date
);
CREATE TABLE t2 (
enddate date
);
CREATE TABLE t3 (
enddate date
);
INSERT INTO t1
VALUES (CURRENT_DATE), (CURRENT_DATE+1);
INSERT INTO t2
VALUES (CURRENT_DATE), (CURRENT_DATE+2), (CURRENT_DATE+2);
INSERT INTO t3
VALUES (CURRENT_DATE+2), (CURRENT_DATE+3);
Query #1
WITH all_dates AS (
SELECT 't1' AS table_name, enddate
FROM t1
UNION ALL
SELECT 't2' AS table_name, enddate
FROM t2
UNION ALL
SELECT 't3' AS table_name, enddate
FROM t3
)
SELECT enddate, ARRAY_AGG(DISTINCT table_name) AS appears_in
FROM all_dates
GROUP BY 1
HAVING COUNT(DISTINCT table_name) > 1
ORDER BY 1;
enddate
appears_in
2022-05-07T00:00:00.000Z
t1,t2
2022-05-09T00:00:00.000Z
t2,t3
View on DB Fiddle
Not sure what format you want the result in. I made two scripts - a simple one and a more detailed one. Perhaps this is what you need
Here is dbfiddle
with data(dt, t) as (
select distinct endate, 0 from straddle0 union all
select distinct endate, 1 from straddle1 union all
select distinct endate, 2 from straddle2 union all
select distinct endate, 3 from straddle3 union all
select distinct endate, 4 from straddle4
)
select dt, min(t) as t from data group by dt having count(*) = 1;

How to select data between two datetimes which are related to certain ID in postgresql

So I have 2 tables. In first table I need to link ID with min and max datetime, which I did with
SELECT id, min (datetime) as earlytime, max(datetime) as latesttime
FROM table1
group by id
as a result I get around 5k with ID and 2 timestamps.
I need to use this info to get rows with ID from table2 where datetime for each ID respectively is between their earlytime and latesttime. Or just rows with ID and time which less than latesttime.
Still can't figure out how to do that.
Came up with something like that
SELECT ID, source, amount, type, datetime
FROM table2
WHERE EXISTS (SELECT ID, min (datetime) as earlytime, max (datetime) as latetime
FROM table1
group by ID)
But I guess it just shows any rows that match ID from table1
Anyone can help me with that?
maybe you can join and get the results like below
select A.*
from table2 A
join
(
SELECT id, min (datetime) as earlytime, max(datetime) as latesttime
FROM table1
group by id
)B
on A.id=B.id and
B.timecol between earlytime and latesttime
You can use a combination of a CTE or sub-query (whichever you prefer) and BETWEEN()to achieve your expected output
with cte as (
select
id
,min(datetime) as earlytime
,max(datetime) as latesttime
from table1
group by id
)
select
c.id
,c.earlytime
,c.latesttime
,t2.* /*Table2 columns*/
from cte as c
inner join table2 as t2 ON c.id = t2.id
and t2.datetime between c.earlytime and c.latesttime
SELECT T2.ID,T2.SOURCE,T2.AMOUNT,T2.TYPE,T2.DATETIME
FROM TABLE2 AS T2
JOIN
(
SELECT id, min (datetime) as earlytime, max(datetime) as latesttime
FROM table1
group by id
)X ON T2.ID=X.ID AND T2.DATETIME BETWEEN X.earlytime AND X.latesttime

How to get Full Record with MAX as aggregate function

I have a table with schema (id, date, value, source, ticker). I wanted to get record having highest ID group by date in sql server
Example Data
ID|date|value|source|ticker
3|10-Dec-2017|10|a|b
1|10-Dec-2017|11|p|q
Below query works in Sqlite. Do we know if I can do same with SqlServer
select max(id), date, value, source, ticker from table group by date
Expected return:-
ID|date|value|source|ticker
3|10-Dec-2017|10|a|b
Also how I can do same operation on UNION of 2 tables with same schema.
You can use subquery :
select t.*
from table t
where id = (select max(t1.id) from table t1 where t1.date = t.date);
However, you can also use row_number() function :
select top (1) with ties *
from table t
order by row_number() over (partition by [date] order by id desc);
You can also do it like below :
select t1.* from table1 t1
join (
select max(id) as id, [date] from table1
group by [date]
) as t2 on t1.id = t2.id
SQL HERE

SQL SUM function inquiry

I'm having a hard time summing up a column on two tables. The scenario is something like this (refer to the image below)
Table 1 may have a lot of rows per Date. But Table 2 may only consists of two rows of data per Date. What I wanted to do is to sum up all Item/Price (Table1) according to their Date and ADD them with another SUM of Item/Price of Table2. The category of SUM is by Date.
I tried any joins statement (left, right or inner) but it does not produce the result that I am expecting to. My expected result is the Result table. But on my query, it produces a very high value.
Thanks.
Use a UNION clause like this:
WITH t(d, p) AS (
SELECT [Date], Price FROM Table1
UNION ALL
SELECT [Date], Price FROM Table2
)
SELECT d, SUM(p) FROM t GROUP BY d
You can do this with UNION ALL in either a subquery or a cte, cte shown here:
;WITH cte AS (SELECT [Date], Price
FROM Table1
UNION ALL
SELECT [Date], Price
FROM Table2
)
SELECT [Date], SUM(Price) AS Total_Price
FROM cte
GROUP BY [Date]
Demo: SQL Fiddle
Try This,
with cte (C_Date,C_Price)
as
(
SELECT date,SUM(price) FROM table_1
group by date
union
SELECT date,SUM(price) FROM table_2
group by date
)
select c_date,SUM(c_price) from cte
group by C_Date
Try this
Select t.date,P1+P2
from(
Select Date,sum(Price) P1
from table1 t
group by Date
) t
left join
(
Select Date,sum(Price) P2
from table t2
group by date
) t1 on t.date = t1.date
group by date

Case on union of multiple unions and issue with alias

I have 2 series of unions which I wish to join by another union. In the first one, I have 3 Selects and in the second one I have 2 different Selects.
Select id, min(value)
from table1 t1
join (Select id, value
Union
Select id, value
Union
Select id, value) as foo
on foo.id=t1.id
Group by id
Select id, max(value)
from table1 t1
join (Select id, value
Union
Select id, value) as bar
on bar.id=t1.id
Group by id
I tried to do a union between these two, but it made things pretty complicated. My biggest issue is with my alias. My second is with the case linked to my value columns, which I wish to name value.
Select (alias).id,
Case
When foo.value= 0 or bar.value=1 THEN 1
Else 0
End as value
from table1 t1
Join (Select id, min(value)
from table1 t1
join (Select id, value
Union
Select id, value
Union
Select id, value) as foo
on foo.id=t1.id
Group by id
UNION
Select id, max(value)
from table1 t1
join (Select id, value
Union
Select id, value) as bar
on bar.id=t1.id
Group by id) as (alias)
on ??.id=??.id
I wrote my case the way I think it should be written, but normally, when there are more than one column with the same name, SQL states it as ambiguous. I am still unsure if I should use UNION or INTERSECT, but I assume either of them would be done the same way. How should I deal with this?
I'm reading this right, you probably want something like this
SELECT ...
FROM ( ... union #1 ) AS u1
JOIN (... union #2 ) AS u2 ON u1.id = u2.id