How to Select distinct data from three tables? - sql-server

How can I write a SQL statement to select distinct data from three tables?
There are three tables
1)
Registration
id name contact
123 abc 123456789
2) bookingReg
PkBkID FkRegID ac_no
1 123 QT123
3) products
PkPro FkBkID pro_name Qty price
1 1 abc 2 150
2 1 def 1 400
3 1 ghi 5 500
4 1 abc 2 150
SELECT * FROM Registration as a
JOIN bookingReg as b ON (b.FkRegID = '123')
JOIN products as c ON (c.FkBkID = b.PkBkID )
I want distinct pro_name
Out put is
ac_no qty price
QT123 8 1050
HOw ?

Answer based on my assumption
SELECT pro_name,
ac_no,
SUM(qty) Sumqty,
SUM(price) SumPrice
FROM Registration a
JOIN bookingReg b
ON b.FkRegID = a.id
JOIN products c
ON c.FkBkID = b.PkBkID
GROUP BY pro_name, ac_no
EDIT Remove ac_no from SELECT and GROUP BY if you don't want to see this field in result.

Pls try this
SELECT A.ac_no, SUM(A.Qty) Qty, SUM(A.Price) Price
FROM
(
SELECT DISTINCT B.ac_no, P.Qty, P.Price
FROM Registration R
INNER JOIN bookingReg B ON B.FkRegID = R.id
INNER JOIN products P ON P.FkBkID = B.PkBkID
) A
GROUP BY A.ac_no

Related

MS SQL Server - Join two tables where ID is equivalent to new ID

I am trying to join two tables but did not able to success
Test Supplier Table
SID NAME
1 Test
2 Test2
Test Stock Table
ID NewID SupID Qty
1 101 1 2
2 102 1 5
3 103 2 6
101 1 4
101 1 7
101 2 5
103 2 10
The output I am looking for
ID NAME Qty
2 Test 5
101 Test 13
101 Test2 5
103 Test2 16
My code is -
Select S.NAME, ST.ID, SUM(ST.Qty)
From Stock ST
Inner Join ST.SupID = S.SID
I need to combine those ID's which are matching with the new ID's with another ID's. If you see the results, I need to combine ID 1 qty with ID 101 because ID 1 has new ID 101 and no need to display ID 1. I have tried inner join but did not work.
First, you find those with NEW ID and those without NEW ID. For those with NewID, use NEWID, for those without use ID (old ID). then you use UNION ALL to combine both result and join to the Supplier table to obtain the NAME.
; with
cte as
(
-- with NewID
select ID = NewID, SupID, Qty = sum(Qty)
from Stock ST
where exists
(
select *
from Stock x
where x.ID = ST.NewID
)
group by NewID, SupID
union all
-- without NewID
select ID, SupID, Qty = sum(Qty)
from Stock ST
where not exists
(
select *
from Stock x
where x.ID = ST.NewID
)
group by ID, SupID
)
select c.ID, SP.NAME, Qty = sum(Qty)
from cte c
inner join Supplier SP on c.SupID = SP.SID
group by c.ID, SP.NAME
Start with the Stock table and join to the Supplier table (remembering to name the table in the join) and then self-left join to the IDs in the Stock table to determine if they exist or not. Then group by on whichever ID you want to keep.
SELECT
COALESCE(ST2.ID, ST.ID) ID
, S.NAME NAME
, SUM(ST.Qty) Qty
FROM Stock ST
INNER JOIN Supplier S
ON ST.SupID = S.SID
LEFT JOIN (
SELECT DISTINCT ID
FROM Stock
) ST2
ON ST.NewID = ST2.ID
GROUP BY
COALESCE(ST2.ID, ST.ID)
, S.NAME

Joining Two Tables, getting Aggregate and unique value of one

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

How to get department wise highest salary and highest salary holder Employee name,consider 3 tables are joined using keys

How to get department wise highest salary and highest salary holder Employee name,consider 3 tables are joined using keys
io/-
emptable, saltable,depttable
id name dept_id id sal dept_id dept_name
1 ram 10 1 100 10 xyz
2 sham 10 2 500 20 abc
3 jadu 20 3 900 30 por
4 john 20 4 999 40 stu
5 Madhu 30 5 300 50 xxx
o/p-
name,sal,dept_name
sham 500 abc
john 999 stu
Madhu300 xxx
SELECT DISTINCT
MAX(amount) OVER (PARTITION BY d.id ORDER BY s.amount DESC) AS sal,
FIRST_VALUE(e.name) OVER (PARTITION BY d.id ORDER BY s.amount DESC) AS emp,
d.name as dept
FROM emptable e
INNER JOIN depttable d
ON e.dept_id = d.id
INNER JOIN saltable s
ON s.id = e.id
I made some assumptions for column names in your tables. You can find my schema script here.
You can JOIN all the table and then use window function row_number to choose top two records per department:
select *
from (
select t.*,
row_number() over (
partition by dept_id order by salary desc
) rn
from (
select e.*,
s.salaray,
d.dept_name
from emptable e
join saltable s on e.emp_id = s.emp_id
join depttable d on d.dept_id = e.dept_id
) t
) t
where rn <= 2;
Your table are missing the column names. So, I assumed the names (hopefully correctly)

CTE duplicate references

for a simple data structure such as so:
ID parentID Name (Table: VehicleType)
1 Vehicle
2 1 Small
3 2 Car
4 2 Motorcycle
5 1 Medium
6 5 Pickup
ID ItemType Name (Table: Vehicle)
1 3 Golf
2 4 125
Is that possible to use CTE to result as:
VehicleType Name
Vehicle Golf
Small Golf
Car Golf
Vehicle 125
Small 125
Motorcycle 125
I want to create registers for every found vehicle type, tried everything without success.
You can use a recursive CTE http://technet.microsoft.com/en-us/library/ms186243(v=sql.105).aspx
;WITH cteRecursiveTypes as
(
SELECT baseTypeID = t.ID, typeID = t.ID, t.parentID, VehicleType = t.Name, recLevel = 1
FROM VehicleType t
UNION ALL
SELECT t.baseTypeID, parentT.ID, parentT.parentID as parentID, VehicleType = parentT.Name, recLevel = t.recLevel + 1
FROM cteRecursiveTypes t
INNER JOIN VehicleType parentT on t.parentID = parentT.ID
)
SELECT t.VehicleType, v.Name, recLevel = dense_rank() over(partition by t.baseTypeID order by t.recLevel desc) - 1
FROM Vehicle v
INNER JOIN cteRecursiveTypes t on v.ItemType = t.baseTypeID
ORDER BY 2,1
;

Combining two queries (MS SQL)

I have two tables
One table connects "client ID" with "product id"
TABLE A
ClientID ProductID
1 2
1 4
1 6
2 3
2 5
Then there is another table that logs the amount of time spent with a product:
TABLE B
ProductID Time Date_added
2 10 (datetime)
4 2 (datetime)
2 3 (datetime)
4 1 (datetime)
How do I combine two queries:
One query to get all the product id's associated with a client
SELECT ProductID FROM TABLE_A where ClientID = 1
Then get a monthly sum of all the time spent with those products?
SELECT SUM(time) from Table_B WHERE DATEPART(month, Date_added) = 8 AND ProductID = (products from the previous query?)
Sounds like you want a join statement, taking a shot in the dark but probably
SELECT A.ClientID,SUM(B.Time)
FROM
TABLE A AS A
LEFT JOIN
TABLE B AS B ON (A.ProductID = B.ProductID)
WHERE
DATEPART(month, B.Date_added) = 8
GROUP BY
A.ClientID
This will show the total of time for all products as grouped by the Client ID. This will also include clients that did not have any time spent on products for the month
You're really very close.
SELECT SUM(B.time)
FROM Table_B B INNER JOIN
Table_A A ON B.ProductID = A.ProductID
WHERE DATEPART(month, B.Date_added) = 8
AND A.ClientID = 1
;
SELECT SUM(time) from Table_B
WHERE DATEPART(month, Date_added) = 8
AND ProductID IN (SELECT ProductID FROM TABLE_A where ClientID = 1)
Updated to use IN instead of =
SELECT SUM(time)
FROM B
Join A on A.productID = B.ProductID
WHERE where a.clientID =1
group my month(b.date);

Resources