Select column from one table order by column from another table - sql

I have 2 tables:
Customer_Master:
CUSTOMER_ID CUSTOMER_NAME
----------------------------
1 Test1
2 Test2
Ticket_Master:
TICKETID CUSTOMER_ID UPDATEDATE
--------------------------------------------------
1 1 2017-03-03 00:00:00.000
2 1 2017-03-20 20:09:31.000
3 2 2017-03-20 20:11:00.000
4 2 2017-03-20 20:15:29.000
I need results with all elements from Table 1 order by updatetime of Ticket_Mater. Join results in Duplicate rows whereas I need distinct rows from Customer_Master.
SELECT
a.CUSTOMER_ID, MAX(b.UPDATEDATE)
FROM
customer_master AS a
INNER JOIN
Ticket_master AS b ON a.CUSTOMER_ID = b.CUSTOMERID
GROUP BY
a.CUSTOMER_ID
ORDER BY
MAX(b.UPDATEDATE) DESC
Above query returns order by update but not all elements of customer_master.
SELECT
a.*, b.UPDATEDATE
FROM
customer_master AS a
INNER JOIN
Ticket_master AS b ON a.customer_id = b.customerid
ORDER BY
b.UPDATEDATE desc
This Query Return Duplicate rows from Ticket_master.
Please help. Every Help will be highly Appreciated.

As there can be several entries in Ticket_Master for a CUSTOMER_ID you must decide by which of the possible dates to sort. This would usually be the first or the latest date per CUSTOMER_ID.
You can do this with a subquery:
select *
from customer_master cm
order by
(
select max(tm.updatedate)
from ticket_master tm
where tm.customer_id = cm.customer_id
) desc;

Try this
SELECT distinct(a.*)
FROM customer_master AS a inner join
Ticket_master AS b ON a.CUSTOMER_ID = b.CUSTOMERID
order by b.UPDATEDATE desc

Related

How to select rows from another table based on a table containing min and max values

TableA:
Userid sessionid domain_value tag
---------------------------------
1 20 amex bank
1 40 visa bank
2 10 citibank bank
2 20 amex bank
2 30 amex bank
TableB:
Userid sessionid(min) sessionid(max)
------------------------------------
1 20 40
2 10 30
3
4
5
How to retrieve all the rows from TableA based on values in TableB?
select *
from TableA a
inner join TableB b on a.userid = b.userid
where a.sessionid between (select b.[sessionid(min)] from TableB b)
and (select b.sessionid(max)] from TableB b)
assumin table B with these column name
Userid, sessionid_min, sessionid_max,
try using just between column_fom_min and column_for_max
select *
from TableA a
inner join TableB b on a.userid = b.userid
where a.sessionid between b.sessionid_min
and b.sessionid_max
How to retrieve all the rows from TableA based on values in TableB?
In order to retrieve rows from TableA, select from TableA. If you want to filter based on values in TableB, place an according WHEREclause in the query. There is no need to join here.
select *
from tablea a
where exists
(
select null
from tableb b
where a.sessionid between b.sessionid_min and b.sessionid_max
)
order by userid, sessionid;
(You can achieve the same with a join, but the intention would not be as clear from reading the query.)
You may try this
select t.Userid ,
(select min(sessionid) from TableA as tb on tb.Userid =t.Userid ) as Min,
(select max(sessionid) from TableA as tb on tb.Userid =t.Userid ) as Max
from TableA as t group by t.Userid

Count similar values from table by combining two tables

I have two table
table A
name id
ABC 1
PQR 2
XYZ 1
QWE 2
DFG 3
Another table
table B
id idname
1 stuart
2 bob
3 alex
expected output
id idname count
1 stuart 2
2 bob 2
3 alex 1
Iam using oracle 9i, Is it possible to obtain the expected result?
I have tried using distinct keyword but its not helping as it provides only the total count
That's simple. Join and count:
select b.id,
b.idname,
count(*) as cnt
from table_a a
join table_b b on a.id = b.id
group by b.id, b.idname;
If you need all the record from table b even if there is no corresponding row in table a, you can use an outer join:
select b.id,
b.idname,
count(a.id) as cnt
from table_a a
right join table_b b on a.id = b.id
group by b.id, b.idname;
Same can be achieved by using a left join:
select b.id,
b.idname,
count(a.id) as cnt
from table_b b
left join table_a a on a.id = b.id
group by b.id, b.idname;
Use JOIN to get data from both tables and use the aggregate function COUNT with GROUP BY.
Query
select t1.id, t1.idname, count(t2.name) as count
from TableB t1
left join TableA t2
on t1.id = t2.id
group by t1.id, t1.idname
order by count(t2.name) desc, t1.id;;

How to SUM Only One Time Per UniqueId in SQL?

I have two tables that look roughly like this:
Table A
DocumentId (*is unique) DocumentDate
1 2016-01-01
2 2016-01-01
3 2016-02-01
4 2016-03-01
and Table B
ContractId SnapshotTimeId NetFinanced
1 20160231 300
1 20160331 300
1 20160431 300
2 20160231 450
2 20160331 450
2 20160431 450
3 20160331 500
3 20160431 500
4 20160431 150
I would like the final table to look something like this:
DocumentDate NetFinanced
2016-01-01 750
2016-02-01 500
2016-03-01 150
I have tried the following and it doesn't work:
SELECT A.DocumentDate, SUM(B.NetFinanced)
FROM A
JOIN B on B.ContractId=A.DocumentId
GROUP BY A.DocumentDate
Any ideas? Thanks in advance
you can use distinct
SELECT A.DocumentDate,
SUM(B.NetFinanced)
FROM A
JOIN (SELECT DISTINCT
ContractId,
NetFinanced
FROM B
) B ON B.ContractId = A.DocumentId
GROUP BY A.DocumentDate
the result of this will be different if the NetFinanced amount changes per SnapshotTimeId
if you want the most recent NetFinanced amount, you can use Row_number() to order the values.
SELECT A.DocumentDate,
SUM(B.NetFinanced)
FROM A
JOIN (SELECT ROW_NUMBER() OVER (PARTITION BY ContractId ORDER BY SnapshotTimeId DESC) Rn,
ContractId,
NetFinanced
FROM B
) B ON B.ContractId = A.DocumentId AND B.Rn = 1
GROUP BY A.DocumentDate
You have duplicate values for NetFinanced in TableB, of course the results won't give you what you want. You need to join TableA with the unique values (I assume) of ContractId and NetFinanced columns from TableB:
SELECT A.DocumentDate,
SUM(B.NetFinanced) NetFinanced
FROM dbo.TableA A
INNER JOIN (SELECT DISTINCT ContractId, NetFinanced
FROM dbo.TableB) B
ON A.DocumentId = B.ContractId
GROUP BY A.DocumentDate;
Try Like this
SELECT A.DocumentDate, SUM(B.NetFinanced)
FROM A
JOIN (SELECT MAX(ContractId) ContractId, MAX(SnapshotTimeId)SnapshotTimeId,
MAX(NetFinanced)NetFinanced
FROM B GROUP BY ContractId) B ON B.ContractId = A.DocumentId
GROUP BY A.DocumentDate

How to get only the most recent record on a group of data?

I need an help to solve this SQL problem: I've a dataset like this
Customer Field A Date
A y 2015-01-21
A z 2015-02-24
B y 2015-02-01
B g 2015-02-25
C z 2015-02-25
C x 2015-03-27
I would like to get ONLY one row per customer and only the most recent record.
So, result must be:
A z 2015-02-24
B g 2015-02-25
C x 2015-03-27
I think I need to get the DISTINCT of all customers and then JOIN them to the same table with a MAX clause on Date field.
Something like this:
SELECT DISTINCT customer FROM mytable a
INNER JOIN mytable b ON a.customer = b.customer
but I don't know how to continue...
Or use a correlated sub-query to find a customer's max date:
SELECT *
FROM mytable a
WHERE Date = (select max(Date) from mytable b
where a.customer = b.customer)
You can self-join on the max date of each customer
SELECT a.*
FROM mytable a
INNER JOIN
(
select customer, max(date_column) as mdate
from mytable
group by customer
) b ON a.customer = b.customer
AND a.date_column = b.mdate

SQL query to find status of the last event of an order

I have two tables (in a SQL Server database) as following:
TblOrders
OrderID (PK)
(some more fields)
TblEvents
EventID (PK)
OrderID (FK) (linked to OrderID of TblOrders)
EventDate
Status
Each event in TblEvents belongs to an order in TblOrders, and each event has a date and a 'status' (a numeric code). An order may have several events (at least one).
I need a SQL query that finds for each OrderID in TblOrders the status of the latest event among all its events. For Example:
Input tables:
TblOrders
=========
OrderID
1
2
3
TblEvents
=========
EventID OrderID EventDate Status
1 1 01/02/2011 4
2 1 02/02/2011 2
3 2 03/02/2011 2
4 3 03/02/2011 3
5 2 01/02/2011 1
Result of the query:
OrderID Status
1 2
2 2
3 3
(OrderID 2 has Status 2 because it has two events, 3 and 5, and the latest of them is Event 3 which has Status 2.)
I hope I've explained myself clearly. I've tried to write the query for long time, but couldn't find the solution, so any help or hint will be welcomed.
select a.OrderID, e.Status
from (
select o.OrderID, max(e.EventDate) latestDate
from TblOrders o
inner join TblEvents e on o.OrderID = e.OrderID
group by o.OrderID
) a
inner join TblEvents e on e.OrderID = a.OrderID
where e.EventDate = a.latestDate
select a.OrderID, a.Status
from TblEvents a
where a.EventDate =
(select max(b.EventDate)
from TblEvents b
where b.OrderId = a.OrderID)
Note this will return multiple rows if more than one record for an Order has the same lastest EventDate.
SELECT q.OrderID, q.Status
FROM (SELECT e.OrderID, e.Status,
ROW_NUMBER() OVER (PARTITION BY e.OrderID ORDER BY EventDate DESC) as RowNum)
FROM tblEvents e) q
WHERE q.RowNum = 1
The same query using a CTE:
;WITH cteRowNum AS (
SELECT e.OrderID, e.Status,
ROW_NUMBER() OVER (PARTITION BY e.OrderID ORDER BY EventDate DESC) as RowNum
FROM tblEvents e
)
SELECT q.OrderID, q.Status
FROM cteRowNum q
WHERE q.RowNum = 1
SELECT TblORDER.ORDERID, MAX(tblEvent.EventDate), tblEvent.Status FROM TblOrder INNER JOIN tblEvent ON tblEvent.OrderID = tbOrder.ORDERID GROUP BY TblORDER.ORDERID... something like that ?
Try This...
SELECT DISTINCT(OrderId) OrderId, Status
FROM tblEvents
ORDER BY EventDate
Select * from TblEvents Where EventID IN(
Select MAX(EventID) from TblEvents Group by OrderID
)
Now Join this with any table you want