How to JOIN two rows into one row SQL - sql

Table 1:
ID
Name
Class
Date
Intime
Outtime
INAM
OUTPM
1
Smith
1st
07-12-2022
8:30 AM
Null
P
Null
1
Smith
1st
07-12-2022
Null
4:30 PM
Null
P
How to join these two rows into a single row?
Required output:
ID
Name
Class
Date
Intime
Outtime
INAM
OUTPM
1
Smith
1st
07-12-2022
8:30 AM
4:30 PM
P
P
Can someone please help me to join into a single row? Thank you...

You may aggregate by the first 4 columns and take the max of the final 4 columns:
SELECT ID, Name, Class, Date,
MAX(Intime) AS Intime, MAX(Outtime) AS Outtime, MAX(INAM) AS INAM,
MAX(OUTPM) AS OUTPM
FROM yourTable
GROUP BY ID, Name, Class, Date;

SELECT
FK,
MAX(Field1) AS Field1,
MAX(Field2) AS Field2
FROM
table1
GROUP BY
FK;
I used MAX, but any aggregate which picks one value from among the GROUP BY rows should work.
Test data:
CREATE TABLE table1 (FK int, Field1 varchar(10), Field2 varchar(10));
INSERT INTO table1 VALUES (3, 'ABC', NULL);
INSERT INTO table1 VALUES (3, NULL, 'DEF');
INSERT INTO table1 VALUES (4, 'GHI', NULL);
INSERT INTO table1 VALUES (4, 'JKL', 'MNO');
INSERT INTO table1 VALUES (4, NULL, 'PQR');
Results:
FK Field1 Field2
-- ------ ------
3 ABC DEF
4 JKL PQR

Related

how to count the number of last day

I got a data like it :
id date_ type
1 05/03/2020 A
2 07/03/2020 A
3 15/03/2020 A
4 25/03/2020 B
5 24/03/2020 B
6 31/03/2020 C
7 31/03/2020 D
I used the function last_day,
I did it :
select last_day(date_) from table1
But I got it :
31/03/2020 : 7
And I want to have it :
31/03/2020 : 2
thanks !
If you are looking for the count of records having last day of the month in date_ field then:
Schema and insert statements:
create table table1(id int, date_ date, type varchar(10));
insert into table1 values(1, '05-Mar-2020', 'A');
insert into table1 values(2, '07-Mar-2020', 'A');
insert into table1 values(3, '15-Mar-2020', 'A');
insert into table1 values(4, '25-Mar-2020', 'B');
insert into table1 values(5, '24-Mar-2020', 'B');
insert into table1 values(6, '31-Mar-2020', 'C');
insert into table1 values(7, '31-Mar-2020', 'D');
Query:
select date_, count(*)cnt
from table1
where date_ = last_day(date_)
group by date_;
Ouput:
DATE_
CNT
31-MAR-20
2
If you need all the date_ with count no need to use last_day:
Query:
select date_, count(*)cnt
from table1
group by date_
order by date_;
Output:
DATE_
CNT
05-MAR-20
1
07-MAR-20
1
15-MAR-20
1
24-MAR-20
1
25-MAR-20
1
31-MAR-20
2
db<>fiddle here
I think you want aggregation:
select date_, count(*)
from t
where date_ = last_day(date_)
group by date_;
The way I understood it, "last day" isn't the result of the LAST_DAY function, but maximum date value in that table. The result you're after is count of rows whose date is equal to that "maximum" date.
If that's so, then this might be one option: counting rows is easy. ROW_NUMBER analytic function calculates ordinal numbers of each row, sorted by date in descending order which means that it is the 1st row you need.
Something like this:
SQL> select date_, cnt
2 from (select date_,
3 count(*) cnt,
4 row_number() over (order by date_ desc) rn
5 from table1
6 group by date_
7 )
8 where rn = 1;
DATE_ CNT
---------- ----------
31/03/2020 2
SQL>

Find sum() from two different tables and join them based on a condition?

I have two tables,
Table1:
ID Amount Date
------------------
123 500.00 02-Sep-2020
123 240.00 02-Sep-2020
124 200.50 02-Sep-2020
125 150.70 03-Sep-2020
123 480.80 03-Sep-2020
Table2
ID Settled_Amount Date
-------------------------------
123 150.25 02-Sep-2020
124 200.00 03-Sep-2020
125 100.40 03-Sep-2020
I want to sum the Amount column of table1 and sum the settled_amount column of Table2 of a particular ID group by the Date column.
So My result would be for ID=123:
Sum(Amount) Sum(Settled_amount) Date
------------------------------------------
740.00 150.25 02-Sep-2020
480.80 03-Sep-2020
You can use union all and group by. For all ids:
select id, date, sum(amount), sum(amount_settled)
from ((select id, date, amount, null as amount_settled
from table1
) union all
(select id, date, null as amount, amount_settled
from table2
)
) t
group by id, date
order by date;
You can filter for a particular id using a where clause in the outer query.
Another way to write it without subseleting as Gordon does.
declare #table1 table (id int, amount numeric(18,2), Dates Date)
Insert into #table1
values
(123 ,500.00 ,'02-Sep-2020'),
(123 ,240.00 ,'02-Sep-2020'),
(124 ,200.50 ,'02-Sep-2020'),
(125 ,150.70 ,'03-Sep-2020'),
(123 ,480.80 ,'03-Sep-2020')
declare #table2 table (id int, Settled_Amount numeric(18,2), Dates Date)
insert into #table2
values
(123 , 150.25 ,'02-Sep-2020'),
(124 , 200.00 ,'03-Sep-2020'),
(125 , 100.40 ,'03-Sep-2020');
with Table1 as (
select sum(amount) as Amount,ID,Dates from #table1
group by ID,Dates
)
,
Table2 as (
Select sum(Settled_amount) as Settled_amount, ID,Dates from #table2
group by ID,Dates
)
select Amount,Settled_amount,a.Dates,a.ID from Table1 a left join table2 b on a.id = b.id and a.Dates = b.Dates
where a.id=123

Sql checking if a date from 1 table is between 2 dates from different table

i have 2 sql tables
has Id, date, boolean value
has Id, date
so table 1 looks like this
1 3/1/2017 false
2 3/1/2017 true
1 1/1/2017 false
2 10/12/2016 false
table 2 like this
1 3/1/2017
2 3/1/2017
1 2/1/2017
1 12/12/2016
The result I want is for each pair of dates in table 1 that have the same id and are following each other for example for id 1 it is 1/1/2017 and 3/1/2017
to find if there is a date in table 2 with the same id that is between those dates (same day inclusive) and the boolean is false.
so for example the result in this case would be
for id1 2/1/2017, 3/1/2017
How can I do this?
How many rows there can be in Table1 with the same ID? I assume 2, but the query will work reasonably even with 1 or 3+.
"are following each other" - any two dates will follow each other, unless they are the same, so the only real check below is for inequality.
"the boolean is false" - there are two rows, which can have different boolean values. I assume both of them have to be false. (false is 0, true is 1)
Sample data
This is how your sample data should be presented in your question. At least you should write dates in a way that we don't have to guess what is month and what is day.
DECLARE #Table1 TABLE (ID int, dt date, Flag bit);
INSERT INTO #Table1 (ID, dt, Flag) VALUES
(1, '2017-01-03', 'false'),
(2, '2017-01-03', 'true'),
(1, '2017-01-01', 'false'),
(2, '2016-12-10', 'false');
DECLARE #Table2 TABLE (ID int, dt date);
INSERT INTO #Table2 (ID, dt) VALUES
(1, '2017-01-03'),
(2, '2017-01-03'),
(1, '2017-01-02'),
(1, '2016-12-12');
Query
WITH
CTE
AS
(
SELECT
ID
,MIN(dt) AS StartDT
,MAX(dt) AS EndDT
,MAX(CAST(Flag AS int)) AS MaxFlag
FROM #Table1 AS Table1
GROUP BY ID
)
SELECT
CTE.ID
,A.dt
FROM
CTE
CROSS APPLY
(
SELECT
Table2.dt
FROM #Table2 AS Table2
WHERE
Table2.ID = CTE.ID
AND Table2.dt >= CTE.StartDT
AND Table2.dt <= CTE.EndDT
) AS A
WHERE
StartDT < EndDT -- "are following each other"
AND MaxFlag = 0 -- "the boolean is false" for both IDs
;
Result
+----+------------+
| ID | dt |
+----+------------+
| 1 | 2017-01-02 |
| 1 | 2017-01-03 |
+----+------------+
Index on Table2 on (ID, dt) will help a lot.

Select SQL Columns as added rows

I have a SQL Server 2008 table as below...
ID Others1Desc Others1Value Others2Desc Others2value
-- ----------- ------------ ----------- ------------
id_x xyz 12.50 pqr 10.00
id_y abc NULL mno 1.05
Now, I want the select result as below...
ID ItemDesc ItemValue
-- ----------- ------------
id_x xyz 12.50
id_x pqr 10.00
id_y abc NULL
id_y mno 1.05
Any guidance is highly appreciated. Thanks
And another way is using cross apply and values clause like this
DECLARE #temp table (ID [varchar](100), Others1Desc [varchar](100), Others1Value decimal(11, 2), Others2Desc [varchar](100), Others2Value decimal(11, 2));
INSERT #temp (ID, Others1Desc, Others1Value, Others2Desc, Others2Value) VALUES ('id_x', 'xyz', 12.50, 'pqr', 10.00);
INSERT #temp (ID, Others1Desc, Others1Value, Others2Desc, Others2Value) VALUES ('id_y', 'abc', NULL, 'mno', 1.05);
select ID, t.* from #temp
cross apply
(
values (Others1Desc, Others1Value),
(Others2Desc, Others2Value)
) t(ItemDesc, ItemValue)
Result
ID ItemDesc ItemValue
--------------------------
id_x xyz 12.50
id_x pqr 10.00
id_y abc NULL
id_y mno 1.05
You can use UNION ALL to do this:
select ID, Others1Desc as ItemDesc, Others1Value as ItemValue
from yourtable
union all
select ID, Others2Desc as ItemDesc, Others2Value as ItemValue
from yourtable
This way:
select ID, Others1Desc as ItemDesc,Others1Value as itemValue from
(select ID , Others1Desc , Others1Value from table1
Union all
select ID , Others2Desc, Others2value from table1)as a

how to get all rows distinct which has date closed with today

I have one table in SQL in this form:
id Name Date
----------------------------
1 john 04/05/2014
2 andi 12/05/2014
3 mark 05/08/2014
4 sofie 05/11/2014
5 john 12/12/2014
5 mark 15/12/2014
and i want to select data in this form "distinct"
id Name Date
---------------------------
1 john 12/12/2014
2 mark 15/12/2014
3 andi 12/05/2014
try something like:
SELECT t1.*
FROM <table_name> t1
WHERE t1.date = (SELECT MAX(t2.date)
FROM <table_name> t2
WHERE t2.name = t1.name)
Try this:
-- sample data
create table #tbl (id int, name nvarchar(20), [date] date);
insert into #tbl (id, name, [date]) values
(1, 'john', '2014-05-04'),
(2, 'andi', '2014-05-12'),
(3, 'mark', '2014-08-05'),
(4, 'sofie', '2014-11-05'),
(5, 'john', '2014-12-12'),
(5, 'mark', '2014-12-15');
-- solution
with ranked as
(
select id, name, [date]
, row_number() over(partition by name order by datediff(day, [date], getdate())) [rank]
from #tbl
)
select id, name, [date] from ranked where [rank] = 1;
-- cleanup
drop table #tbl;
Result
ID NAME DATE
----------------------
2 andi 2014-05-12
5 john 2014-12-12
5 mark 2014-12-15
4 sofie 2014-11-05
This solution ranks original dataset by name and in case when there are the same names ranks them by count of days between today and [date]. So the result dataset consists of rows with the unique names and the rows with names which [date] is closest to today.
Check SQLFiddle
Looks like you may want
SELECT name, MAX(date)
FROM table
GROUP BY name
However, from your example it's impossible to infer on what criterion you'd exclude sofie (and what does a duplicate id mean in your example table -- id is normally used to denote a unique identifier).