I want to fetch data for below scenario [closed] - sql

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Table 1 Table2
Name Month Cast Month
-------------------------- ----------------
Client1 Jan 200 Jan
Client1 Feb 150 Feb
Client2 Jan 110 Mar
Client2 Apr 120 .
.
Dec
Ouput
-----------------------
Name Month Cast
--------------------------
Client1 Jan 200
Client1 Feb 150
Client1 Mar 0
Client1 Apr 0
...
....
Client2 Jan 110
Client2 Feb 0
Client2 Mar 0
Client2 Apr 120
Client2 May 0
.....
....
Result must show all clients with all the months (if not cast to 0) which may not present in table 1.
I've tried right outer and cross join...no result.

You can try this below script-
SELECT A.Name,B.month,COALESCE(C.Cast,0) Cast
FROM (
SELECT DISTINCT 1 CN, Name FROM Table1
) A
INNER JOIN (
SELECT 1 CN, month FROM Table2
) B ON A.CN = B.CN
LEFT JOIN Table1 C
ON A.Name = C.Name
AND B.month = C.Month

You have to create the Cartesian product first (cte ClientMonth)- then join back to the original table to get the data you want...
With ClientMonth as (
select Distinct Name,t2.[Month]
from Table_1 t1
Cross Join Table_2 t2
)
Select cm.Name, cm.[Month], isnull(amt,0)
from ClientMonth cm
Left Join Table_1 t3 on t3.Name = cm.Name and t3.Month = cm.Month

Try it.
SELECT name, m1 as month ,max(cast) as cast from
(
SELECT [id]
,[name]
,b.month as m1
,case when a.month =b.month then [cast] else 0 end as cast
FROM [Table_1] a,[Table_2] b
)c
group by name,m1
order by name

Related

Fetching latest records of individual by joining 2 tables

I have to fetch the latest record of the student which derived by joining 2 tables:
table 1: table 2:
id name id marks EXAM attended time status
-------- ----------------------------------------------
1 ABC 1 90 2019-04-05 06:00:00 PASS
2 DEF 1 25 2018-06-05 08:00:00 FAIL
2 45 2019-03-05 06:00:00 FAIL
2 22 2019-01-05 09:00:00 FAIL
On joining both tables I got this:
# name marks EXAM ATTENDED TIME status
------------------------------------------------------
1 ABC 90 2019-04-05 06:00:00 PASS
2 ABC 25 2018-06-05 08:00:00 FAIL
3 DEF 45 2019-03-05 06:00:00 FAIL
4 DEF 22 2019-01-05 09:00:00 FAIL
5 DEF 55 2019-04-05 09:00:00 PASS
6 DEF 66 2019-05-05 09:00:00 PASS
7 DEF 99 2018-05-05 09:00:00 PASS
I want to fetch the latest result on datetime and name.
The output I need is:
id name marks EXAM ATTENDED TIME status
------------------------------------------------------
1 ABC 90 2019-04-05 06:00:00 PASS
6 DEF 66 2019-05-05 09:00:00 PASS
You can try below using correlated subquery
select * from table1 a1
inner join table2 a on a1.id=a.id
where exam_attended_time in (select max(exam_attended_time) from table2 b where a.id=b.id)
OR you can use row_number() if your db supports it-
select * from
(
select a.name,a1.*,row_number(partition by a.id order by exam_attended_time desc)rn from table1 a1
inner join table2 a on a1.id=a.id
)X where rn=1
You could use a window function (ROW_NUMBER).
SELECT
x.id
, x.NAME
, x.marks
, x.ExamAttendTime
, x.status
FROM
(
SELECT
t1.id
, t1.NAME
, t2.marks
, t2.ExamAttendTime
, t2.status
, ROW_NUMBER() OVER (PARTITION BY t1.id ORDER BY t2.ExamAttendTime DESC) AS ROWNUMBER
FROM
dbo.Table1 t1
JOIN dbo.Table2 t2 ON t2.id = t1.id
) x
WHERE
x.ROWNUMBER = 1
i don't know how you fetch the record like marks '99' and '66' and EXAM attended time
'2019-05-05 09:00:00 ' which is not available in table itself.
though this will might help you on getting correct data .
select a.id,a.name,b.marks,b.[EXAM attended time],b.[status] from table 1 a
join table 2 b on a.id=b.id where [EXAM attended time] in
(select max([EXAM attended time])[EXAM attended time]from exam group by id)
IF you are using SQL SERVER then you can use TOP as below to fetch latest records
SELECT A.id,
A.name,
B.marks,
B.EXAM_attended_time,
B.Status
FROM table1 A
OUTER APPLY (SELECT TOP 1 *
FROM table2 B WHERE B.id = A.id
ORDER BY B.EXAM_attended_time DESC) B
WHERE B.ID = A.id

SQL Output with multi join on different rows

I'm trying to join 2 different data sets with different columns and when I make the join I get repeated results.
My input dataset1 with actual data:
Cust_id Year sales
----------------------
1 2016 679862
1 2017 705365
1 2018 195662
1 2019 201234
2 2016 51074
2 2017 50611
2 2018 19070
2 2019 20123
My input dataset2 with estimated data:
Cust_id Year salesest
-------------------------
1 2018 779862
1 2019 125662
2 2017 23456
2 2018 32856
2 2019 26602
Desired output:
Cust_id Year sales salesest
-------------------------------
1 2016 679862 null
1 2017 705365 null
1 2018 195662 779862
1 2019 201234 125662
2 2016 51074 null
2 2017 50611 23456
2 2018 19070 32856
2 2019 20123 26602
This is what I have tried:
select
a.*, b.salesest
from
tab1 a, tab2 b
where
a.Cust_id = b.Cust_id
You want a LEFT JOIN. The correct syntax is:
select a.*, e.salesest
from actuals a left join
estimates e
on a.Cust_id = e.Cust_id and
a.year = e.year;
you also need to specify the year - and make an outer join for the times when there is no corresponding year in the other table.
select a.*, b.salesest
frpm tab1 a, tab2 b
where
a.Cust_id=b.Cust_id
AND a.YEAR = b.YEAR (+)

How can I generate sql matrix

How I can create this matrix from the tables in sql query? I have table which show how many goods was sold. I want show title of goods instead id of goods. But it's important that fields toy1, toy2 and toy3 have datatype decimal(20,8)
Table 1
id year toy1 toy2 toy3
-------------------------------
-1 1 3 2
1 2016 100 20 50
2 2017 150 120 40
Table 2
id toy
---------------
1 doll
2 car
3 bear
Result matrix
id year toy1 toy2 toy3
-------------------------------
-1 doll bear car
1 2016 100 20 50
2 2017 150 120 40
For SQL Server i will do some left joins
SELECT T.id,
T.year,
CASE
WHEN T1.TOY IS NULL THEN CAST(T.[toy1] AS VARCHAR) ELSE T1.TOY
END [toy1],
CASE
WHEN T2.TOY IS NULL THEN CAST(T.[toy2] AS VARCHAR) ELSE T2.TOY
END [toy2],
CASE
WHEN T3.TOY IS NULL THEN CAST(T.[toy3] AS VARCHAR) ELSE T3.TOY
END [toy3]
FROM <Table1> T
LEFT JOIN <Table2> T1 ON T1.ID = T.toy1
LEFT JOIN <Table2> T2 ON T2.ID = T.toy2
LEFT JOIN <Table2> T3 ON T3.ID = T.toy3;
Result :
id year toy1 toy2 toy3
-1 NULL doll bear car
1 2016 100 20 50
2 2017 150 120 40
This is a very bad data model.
A table should represent an entity, such as a toy, an order, yearly sales, ... A column on the other side represents an attribute of that entity, e.g. the toy's name or price, the order's date, the sale's year. In your model you are mixing this. What is "toy1"? A toy ID? An amount? A mix of both it seems. Then your table 2 allows for many, many toys, whereas your table1 allows for only 3. That doesn't match.
What you should have instead:
table toys
toy_id | name
-------+-----
1 | doll
2 | car
3 | bear
table sales
year | toy_id | amount
2016 | 1 | 100
2016 | 2 | 20
2016 | 3 | 50
2017 | 1 | 150
2017 | 2 | 120
2017 | 3 | 40
And you wouldn't write a query to give you the matrix either. You would select the data (e.g. select * from sales order by year, toy_id) and have your app handle the display. It is easy to fetch the data in a loop with whatever programming language, be it C#, Visual Basic, Java, PHP, whatever, and display it in a grid.
In an SQL query you must know the columns beforehand, but this is not the case with your matrix output, as you would have to know how many toys are in the toys table before running or even writing the query. Everytime you added a toy, you'd have to alter your query. This is not how relational databases are supposed to work.
I am not sure but something like this:
SELECT T1.id,
year,
CASE WHEN T1.Toy1 = T2.id AND T1.id=-1 THEN T2.toy
ELSE T1.Toy1
END AS Toy1,
CASE WHEN T1.Toy2 = T2.id AND T1.id=-1THEN T2.toy
ELSE T1.Toy2
END AS Toy1,
CASE WHEN T1.Toy3 = T2.id AND T1.id=-1 THEN T2.toy
ELSE T1.Toy3
END AS Toy3
FROM Table1 T1
LEFT JOIN Table2 T2 ON T1.id=-1 AND T2.id IN (T1.Toy1, T1.Toy2, T1.Toy3)
One way is to only select the -1 row and apply the algorithms to get the toy names. That can be UNION ALL with the rest of the table that is not the -1 row.
You will have to Cast the output as varchar to mix words and numbers:
DECLARE #table1 TABLE (id int, [year] int, toy1 int, toy2 int, toy3 int)
DECLARE #table2 TABLE (id int, toy varchar(100))
INSERT INTO #table1 VALUES (-1, null, 1, 3, 2), (1, 2016, 100,20,50), (2,2017,150,120,40)
INSERT INTO #table2 VALUES (1,'doll'), (2,'car'), (3,'bear')
-- for the -1 row
SELECT T1.id, COALESCE(CAST(year as varchar), '') AS year
,(SELECT toy FROM #table2 T2 WHERE T2.id = T1.toy1) AS toy1
,(SELECT toy FROM #table2 T2 WHERE T2.id = T1.toy2) AS toy2
,(SELECT toy FROM #table2 T2 WHERE T2.id = T1.toy3) AS toy3
FROM #table1 T1
WHERE T1.id = -1
UNION ALL
--all other rows
SELECT T3.id
,CAST(T3.year as varchar)
,CAST(T3.toy1 as varchar)
,CAST(T3.toy2 as varchar)
,CAST(T3.toy3 as varchar)
FROM #table1 T3
WHERE T3.id <> -1
Gives output:
id year toy1 toy2 toy3
-1 doll bear car
1 2016 100 20 50
2 2017 150 120 40

Merging two rows of data and getting distinct count

This question is in continuation to Merging every two rows of data in a column in SQL Server
My eventtable structure..
Id UserId EventId EventDateTime
1 1 A 18-06-2013 10:36
2 1 B 18-06-2013 10:40
3 1 C 18-06-2013 10:46
4 1 D 18-06-2013 10:50
5 1 A 18-06-2013 13:36
From the earlier question I got data in the following format..
UserId EventStart EventEnd
1 A B
1 B C
Now I would like to get the count of Unique 'EventStart' and 'EventEnd' and filter them by UserId and Date/s
The Report format is
EventStart EventEnd Count
A B 5
B C 3
I know that i could use the data from the previous Question query and store it in a table and try as suggested here
But it would be great if I could get the data straight from the 'eventtable' to the report format with the 'UserId' and 'Date' filters
Any help is sincerely appreciated..
Thanks..
If you just want to count the occurrences, use group by in essentially the same query:
select eventstart, eventend, count(*)
from (select userId, eventid as eventstart,
(select top 1 t2.eventid
from mytable t2
where t2.userid = t.userid and
t2.id > t.id
order by t2.id
) as eventend
from mytable t
) t
where eventend is not null
group by eventstart, eventend;

Issue with SQL Query with Group By [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
Table 1
Id(Key) Name
1 XYZ
2 ABC
Table 2
ID(Key) Bank
1 SC
2 CP
Table 3
Id(no key) month year noofduty
1 03 12 20
2 04 12 22
1 03 12 25
2 04 12 15
Required Result
ID Name Bank TotalDuty
1 XYZ SC 42
2 ABC CP 40
I am confused with GroupBy in multiple tables, a help is required. using SQL 2000 Server
Here is a SQL Fiddle with a Demo
SELECT t1.id
, t1.name
, t2.bank
, sum(t3.noofduty) as totalduty
FROM t1
INNER JOIN t3
on t1.id = t3.id
INNER JOIN t2
ON t2.id = t3.id
GROUP BY t1.id, t1.name, t2.bank