Basically I have 2 tables. Lets say A and B.
A has columns like id(PK), pin, name, address
id(PK) pin name address
1 aaa-111-aaa AAA ------
2 bbb-222-bbb BBB ------
3 ccc-333-ccc CCC --------
B has columns like appName, apprequestTime, appAccectTime, id(FK).
appName apprequestTime appAccectTime id(FK).
LLL 2012-4-01 2012-4-01 1
NNN 2012-4-08 2012-5-01 2
QQQ 2012-4-05 2012-4-01 1
MMM 2012-4-02 2012-4-02 2
PPP 2012-5-01 2012-5-01 1
There can be multiple id rows in the B table as it is Foreign Key.
Now, the problem is I am trying to get all the records of one pin of a certain apprequestTime.
I am trying inner join but it shows the pin because of the id in table B.
pin apprequestTime
aaa-111-aaa 2012-4-01
aaa-111-aaa 2012-4-05
bbb-222-bbb 2012-4-08
bbb-222-bbb 2012-4-02
but the result I am expecting should be:
pin apprequestTime
aaa-111-aaa 2012-4-01
2012-4-05
bbb-222-bbb 2012-4-08
2012-4-02
Can any one help:)
In SQL Server 2005+ you can use row_number() for this type of request:
;with cte as
(
select a.pin, b.apprequestTime,
row_number() over(partition by a.pin
order by b.apprequestTime) rn
from tablea a
inner join tableb b
on a.id = b.id
)
select case when rn = 1 then pin else '' end pin,
apprequestTime
from cte;
See SQL Fiddle with Demo
Or without CTE:
select case when rn = 1 then pin else '' end pin,
apprequestTime
from
(
select a.pin, b.apprequestTime,
row_number() over(partition by a.pin
order by b.apprequestTime) rn
from tablea a
inner join tableb b
on a.id = b.id
) t1
See SQL Fiddle with Demo
Related
This may have been answered previously, but I'm having a difficult time describing my issue.
Let's say I have two tables
Table1
User, CalendarID
Joe 1
Joe 2
Joe 3
Sam 4
Bob 1
Jim 2
Jim 3
Table2
CalendarID, CalendarTime
1 2014-08-18 00:00:00.000
2 2015-01-19 00:00:00.000
3 2015-08-24 00:00:00.000
4 2016-01-18 00:00:00.000
What I would like to do is Join the two tables, only getting a single User Name, and Calendar ID based on what is this highest CalendarTime associated with that CalandarID.
So I would like the query to return
User CalendarID
Joe 3
Sam 4
Bob 1
Jim 3
The closest I've managed is
SELECT t1.User, MAX(t2.CalendarTIme) AS CalendarTime
FROM table1 t1
INNER JOIN table2 as t2
ON t1.CalendarID = t2.CalendarID
Group By t1.User
Which gets me the User and CalendarTime that I want, but not the Calendar ID, which is what I really want. Please help.
Closest to your script and pretty straightforward:
SELECT t1.User, t2.*
FROM table1 t1
INNER JOIN table2 as t2
ON t1.CalendarID = t2.CalendarID
WHERE NOT EXISTS
(
SELECT 1 FROM table1 t1_2
INNER JOIN table2 t2_2
ON t2_2.Calendar_ID = t1_2.Calendar_ID
WHERE t1_2.User = t1.User
AND t2_2.CalendarTime > t2.CalendarTime
)
This can be solved for the top N per group:
using top with ties with row_number():
select top 1 with ties
t1.User, t1.CalendarId, t2.CalendarTime
from table1 t1
inner join table2 as t2
on t1.Calendarid = t2.Calendarid
order by row_number() over (partition by t1.User order by t2.CalendarTime desc)
or using common table expression(or a derived table/subquery) with row_number()
;with cte as (
select t1.User, t1.CalendarId, t2.CalendarTime
, rn = row_number() over (partition by t1.User order by t2.CalendarTime desc)
from table1 t1
inner join table2 as t2
on t1.Calendarid = t2.Calendarid
)
select User, CalendarId, CalendarTime
from cte
where rn = 1
I have 2 tables, TableA in which I have ID and Name columns
id name
1 Turret Punch Press
2 Laser Machine
3 Press Brake
4 Other machines
and Table B in which I am passing Id of Table A as CSV value like this
id TableACSV
1 1,2
2 1,3
My query will be something like
Select
id, TableACSV
from tableB
where (--here i am having problem with query--)
The output I want should be like this
id TableACSV
1 Turret Punch Press,Laser Machine
2 Turret Punch Press,Press Brake
I know this might be a bad practice to do .. but currently i need this ..
Using a CSV splitter DelimitedSplit8K
; WITH CTE AS
(
SELECT b.id, a.name
FROM TableB b
CROSS APPLY dbo.DelimitedSplit8K(b.TableACSV, ',') c
INNER JOIN TableA a on c.Item = a.id
)
SELECT DISTINCT c.id, STUFF(d.name, 1, 1, '') AS TableACSV
FROM CTE c
CROSS APPLY
(
SELECT ',' + x.name
FROM CTE x
WHERE x.id = c.id
FOR XML PATH ('')
) d (name)
How I can do select a primary key in grouping by clause, and it will return max value from another table which not in group by clause? For example :
Table A :
ID table_b_id Value
1 1 100
2 1 200
3 1 150
4 2 300
5 2 200
6 2 100
7 3 100
8 3 200
Table B
ID Name
1 A
2 B
3 C
Result Expected
B.ID B.Name A.ID
1 A 2
2 B 4
3 C 8
I've try some queries like this :
select b.id, max(b.name), max(a.id) as kd_rec
from table_a a join table_b
on a.table_b_id = b.id
group by b.id
I don't know how to get max value from table a group by b.
If you don't want the Name from tableB, then
Query
;with cte as
(
select rn=row_number() over
(
partition by table_b_id
order by [Value] desc
),*
from tableA
)
select table_b_id as [B.ID],
ID as [A.ID]
from cte
where rn=1;
Fiddle demo
If you want the Name also in the result set, then
Query
;with cte as
(
select rn=row_number() over
(
partition by table_b_id
order by [Value] desc
),*
from tableA
)
select t1.table_b_id as [B.ID],
t2.Name as [B.Name],
t1.ID as [A.ID]
from cte t1
join tableB t2
on t1.table_b_id=t2.ID
where t1.rn=1;
Fiddle demo
I have two tables with identical definition.
T1:
Name VARCHAR(50)
Qty INT
T2:
Name VARCHAR(50)
Qty INT
This is the data each table has:
T1:
Name Qty
a 1
b 2
c 3
d 4
T2:
Name Qty
a 1
b 3
e 5
f 10
I want to have result which can sum the Qty from both the tables based on Name.
Expected resultset:
Name TotalQty
a 2
b 5
c 3
d 4
e 5
f 10
If am do Left Join or Right Join, it is not going to return me the Name from either of the tables.
What i am thinking is to create a temp table and add these records and just do a SUM aggregate on Qty column but i think there should be a better way to do this.
This is how my query looks like which does not return the expected resultset:
SELECT t1.Name, ISNULL(SUM(t1.Qty + t2.Qty),0) TotalQty
FROM t1
LEFT JOIN t2
ON t1.Name = T2.Name
GROUP BY t1.Name
Can someone please tell me if creating a temp table is OK here or there is a better way to do this?
You can use a full outer join:
SELECT
ISNULL(t1.Name, t2.Name) AS Name,
ISNULL(t1.Qty, 0) + ISNULL(t2.Qty, 0) AS TotalQty
FROM t1
FULL JOIN t2 ON t1.Name = T2.Name
See it working online: sqlfiddle
You can use a UNION ALL to select both tables as one, since they have the same definition. From there, you can nest them as a derived table, and then SUM on that:
SELECT [Name], SUM(Qty) AS TotalQty
FROM (
SELECT [Name], Qty
FROM t1
UNION ALL
SELECT [Name], Qty
FROM t2
) YourDerivedTable
GROUP BY [Name]
This should be simple enough, but somehow my brain stopped working.
I have two related tables:
Table 1:
ID (PK), Value1
Table 2:
BatchID, Table1ID (FK to Table 1 ID), Value2
Example data:
Table 1:
ID Value1
1 A
2 B
Table 2:
BatchID Table1ID Value2
1 1 100
2 1 101
3 1 102
1 2 200
2 2 201
Now, for each record in Table 1, I'd like to do a matching record on Table 2, but only the most recent one (batch ID is sequential). Result for the above example would be:
Table1.ID Table1.Value1 Table2.Value2
1 A 102
2 B 201
The problem is simple, how to limit join result with Table2. There were similar questions on SO, but can't find anything like mine. Here's one on MySQL that looks similar:
LIMITing an SQL JOIN
I'm open to any approach, although speed is still the main priority since it will be a big dataset.
WITH Latest AS (
SELECT Table1ID
,MAX(BatchID) AS BatchID
FROM Table2
GROUP BY Table1ID
)
SELECT *
FROM Table1
INNER JOIN Latest
ON Latest.Table1ID = Table1.ID
INNER JOIN Table2
ON Table2.BatchID = Latest.BatchID
SELECT id, value1, value2
FROM (
SELECT t1.id, t2.value1, t2.value2, ROW_NUMBER() OVER (PARTITION BY t1.id ORDER BY t2.BatchID DESC) AS rn
FROM table1 t1
JOIN table2 t2
ON t2.table1id = t1.id
) q
WHERE rn = 1
Try
select t1.*,t2.Value2
from(
select Table1ID,max(Value2) as Value2
from [Table 2]
group by Table1ID) t2
join [Table 1] t1 on t2.Table1ID = t1.id
Either GROUP BY or WHERE clause that filters on the most recent:
SELECT * FROM Table1 a
INNER JOIN Table2 b ON (a.id = b.Table1ID)
WHERE NOT EXISTS(
SELECT 1 FROM Table2 c WHERE c.Table1ID = a.id AND c.BatchID > b. BatchID
)