Getting values based on other column - sql

I have the following data in SQL.
NAME,DATE,REF
Pat1,2021-07-15,5072
'',NULL,5072
'',NULL,5072
'',NULL,5072
'',NULL,5072
Pat2,2021-07-15,5073
Is there a way using SELECT QUERY that we can replace the NULL values in DATE column based on the REF values?
Like replace the NULL values with the first available date for matching REF value, without making any change to the database.
Expected Result
NAME,DATE,REF
Pat1,2021-07-15,5072
'',2021-07-15,5072
'',2021-07-15,5072
'',2021-07-15,5072
'',2021-07-15,5072
Pat2,2021-07-15,5073

You can do it with MAX() window function:
SELECT NAME,
COALESCE(DATE, MAX(DATE) OVER (PARTITION BY REF)) DATE,
REF
FROM tablename
See the demo.

Have a derived table (the subquery) to return each ref's date. JOIN:
select t1.NAME, t2.date, t1.REF
from tablename t1
join (select ref, max(date) date
from tablename
group by ref) t2
on t1.ref = t2.ref

Related

How to compare results from sub query in main query

I want to compare results from subquery with the column in main query
--this returns multiple rows
select id, MAX(created_date) as maxdate from table
group by id
I want to use the result set in the another query to compare date (already exist in the table) with created_date for matching id, since sub query is return multiple rows unable to use it in a sub query I get the following error More than one value was returned by a subquery..
Any help is appreciated
Something like this
select t1.id, t1.created_date, t2.maxdate
from table1 as t1
join (
select id, MAX(created_date) as maxdate from table1
group by id
) as t2 on
t1.id = t2.id

How to exclude all rows with the same ID based on one record's value in psql?

Say I have the results above, and want to exclude all rows with ID of 14010497 because at least one of the rows has a date of 2/25. How would I filter it down? Using a WHERE table.end_date > '2019-02-25' would still include the row with a date of 2-23
Try something like this:
select * from your_table
where id not in (
select distinct id
from your_table
where end_date > '2019-02-25'
)
/
I would use not exists:
select t.*
from t
where not exists (select 1
from t t2
where t2.id = t.id and t2.end_date = '2019-02-25'
);
I strongly advise using not exists over not in because it handles NULL values much more intuitively. NOT IN will return no rows at all if any value in the subquery is NULL.

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

Sum values from different tables

I read some topics about this but I'm not very good with sql. I have 10 tables with these fields:
value
type
date
I want to sum all the value fileds together when they have a specific type. I was trying to do something like this, but it's not working.
select sum(tab1.value) + sum(tab2.value)
from tab1, tab2
where tab1.type = tab2.type = 'box'
I guess I could do many simple queries like these and then sum all the results
select sum(value) from tab1 where type='box'
select sum(value) from tab2 where type='box'
but I wonder if I can do one single query
thanks
Having multiple tables with the same structure is usually a sign of poor database design.
I would suggest that you use your last approach, but put the subqueries in the from clause and then add the results in the select:
select t1.value + t2.value + . .
from (select sum(value) as value from tab1 where type='box') t1 cross join
(select sum(value) as value from tab2 where type='box') t2 cross join
. . .
Alternatively, you could union all them together in the from clause and then take the sum:
select sum(value)
from ((select sum(value) as value from tab1 where type='box') union all
(select sum(value) as value from tab2 where type='box') union all
. . .
) t;
If the tables are not linked via FK/PK you can use multiple sub-queries:
SELECT (SELECT SUM(tab1.value) FROM tab1 WHERE type='box') as Tab1Sum,
(SELECT SUM(tab2.value) FROM tab2 WHERE type='box') as Tab2Sum -- and so on...
This yields a single record where each column is the sum of each table.
1.Use single select;
DECLARE #type NVARCHAR(255) = N'Box';
SELECT (SELECT SUM(value) FROM tab1 WHERE type=#Box)
+ (SELECT SUM(value) FROM tab2 WHERE type=#Box)
+ (SELECT SUM(value) FROM tab3 WHERE type=#Box)
+ (...)
I think it's simplest one.
2.you create a view as
CREATE VIEW tabs
AS
SELECT value, type FROM tab1
UNION
SELECT value, type FROM tab2
UNION
SELECT value, type FROM tab3
UNION
...
Then
SELECT SUM(value) FROM tabs WHERE type = 'BOX'
3.Think why similar column are different tables. Can they be merged into single table?
If answer is No, and you have too many tables, consider concatenate SQL strings and use sp_executesql to execute it.

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