Transact SQL - which Join to Use - sql-server

I have two simple SELECT statements:
The first shows a list of Features.
SELECT * FROM Features
id name
-- ----
1 24 Hour Access
2 24 hour CCTV monitoring
3 Airport location
4 Break-Out Areas
5 Business Lounge
6 Business park location
snip..
and the second statement shows a list of feature information that has changed
SELECT
*
FROM
#SmartFeaturesToUpdate new_features
ORDER BY
new_features.centre_translation_id,
new_features.feature_id,
new_features.feature_selected
feature_id centre_translation_id feature_selected
---------- --------------------- ----------------
1 1 1
2 1 1
5 1 1
10 1 1
11 1 1
snip..
What I want to see is all of the features by centre translation.
Combining the tables gives me:
SELECT
*
FROM
#SmartFeaturesToUpdate new_features
LEFT JOIN Feature feature ON feature.id = new_features.feature_id
ORDER BY
new_features.centre_translation_id,
new_features.feature_id,
new_features.feature_selected
feature_id centre_translation_id feature_selected id name
---------- --------------------- ---------------- -- ----
1 1 1 1 24 Hour Access
2 1 1 2 24 hour CCTV monitoring
5 1 1 5 Business Lounge
10 1 1 10 Double Glazing
11 1 1 11 Elevator
snip..
The result above is missing feature id's 3 and 4, because they are not in the second list.
but the result I need is:
feature_id centre_translation_id feature_selected id name
---------- --------------------- ---------------- -- ----
1 1 1 1 24 Hour Access
2 1 1 2 24 hour CCTV monitoring
3 1 1 3 Airport Location
4 1 1 4 Break-Out Area
5 1 1 5 Business Lounge
snip..
How should I modify the third SELECT statement to acheive this and combine the results from both the features and feature information list?

As the comments alluded, I needed another table which linked Features to centre_translation_ids
First get all of the feature / centre_translation varients
SELECT
[centre_translation_id] = centre_translation.id,
feature.id,
feature.name
INTO #AllTheFeatures
FROM
CentreTranslation centre_translation
CROSS JOIN Feature feature
ORDER BY
centre_translation.id,
feature.id
Now we can simply perform the LEFT JOIN
SELECT
all_features.centre_translation_id,
all_features.id,
all_features.name,
smart_features.feature_selected
FROM
#AllTheFeatures all_features
LEFT JOIN #SmartFeaturesToUpdate smart_features ON smart_features.centre_translation_id = all_features.centre_translation_id AND
smart_features.feature_id = all_features.id
ORDER BY
all_features.centre_translation_id,
all_features.id
This gives the results:
centre_translation_id id name feature_selected
--------------------- -- ---- ----------------
1 1 24 Hour Access 1
1 2 24 hour CCTV monitoring 1
1 3 Airport location NULL
1 4 Break-Out Areas NULL
1 5 Business Lounge 1

Why don't you just put it in one query?
SELECT
centre_translation.id AS centre_translation_id,
feature.id,
feature.name,
smart_features.feature_selected
FROM
CentreTranslation centre_translation
CROSS JOIN Feature feature
LEFT JOIN #SmartFeaturesToUpdate smart_features
ON smart_features.centre_translation_id = all_features.centre_translation_id
AND smart_features.feature_id = all_features.id
ORDER BY
centre_translation.centre_translation_id,
feature.id

Related

SQL select joined 2 tables same as one column

SQL table Authority is:
AuthorNo Price PrePay(bit)
----------------------------
1 250$ 1
2 120$ 0
3 300$ 0
4 112$ 1
5 25$ 0
Table Order is:
AuthorNo OrderNo
-----------------
1 33
1 34
2 33
2 38
3 41
3 82
4 55
4 21
5 21
5 66
I want the result is:
Select from Authority.AuthorNo where AuthorNo same in Order.OrderNo and at least one of the AuthorNo.Prepay is 1
AuthorNo
--------
1
2
4
5
How to select this?
If you need to find the authors that have orders that were also ordered by authors with PrePay?
Then you could use an EXISTS for this.
SELECT auth.AuthorNo
FROM Authority auth
JOIN [Order] ord ON ord.AuthorNo = auth.AuthorNo
WHERE EXISTS
(
SELECT 1
FROM [Order] ord_pp
JOIN Authority auth_pp
ON auth_pp.AuthorNo = ord_pp.AuthorNo
AND auth_pp.Prepay = 1
WHERE ord_pp.OrderNo = ord.OrderNo
)
GROUP BY auth.AuthorNo;
A test here
Result:
AuthorNo
--------
1
2
4
5
I am guessing you just want to see the AuthorNo in the result? Try this
Select distinct a.AuthorNo
From Authority a
join Order b on a.AuthorNo=b.AuthorNo
where a.Prepay=1

Linking tables on date basis

I am having two tables as below
Child_Attendance
childid updatedon presentdays
1 31/01/2018 20
1 28/02/2018 15
1 31/03/2018 18
1 30/04/2018 24
1 31/05/2018 17
1 30/06/2018 19
2 31/03/2018 25
2 30/04/2018 28
2 31/05/2018 22
2 30/06/2018 23
And the Second table as
childid class admissiondate
1 creches 15/06/2017
1 balwari 01/02/2018
2 creches 01/01/2017
2 balwari 01/01/2018
2 Bridge Course 01/04/2018
Now, I need a query to return childid,updatedon,presentdays,class.
I am new to sql and don't have any idea how to do it.
I have tried
SELECT t1.childid,t1.updatedon,t1.presentdays,t2.class
FROM child_attendance t1 LEFT JOIN class_allocation t2
ON t1.childid = t2.childid
AND t1.updatedon >= t2.admissiondate
My output should be like this
You can see the child 1 was admitted in creche on dated 15/06/2017 and balwari on dated 01/02/2018. This means he was in creche from 15/06/2018 till 01/02/2018.
I think this query could get what you want:
SELECT t1.childid, t1.updatedon, t1.presentdays,
class=(SELECT TOP (1) class
FROM Class_Allocation
WHERE childid=t1.childid
AND t1.updatedon>=admissiondate
ORDER BY admissiondate DESC)
FROM Child_Attendance t1

SQL Server Multiple Counts in the same Query

I'm sure there is an easy way to do this but I've been struggling with this one...
Suppose I have an order table like so:
OrderId OrderStatus DriverId TripId
------- ----------- ------ ----
1 Available 5 2
2 Available 5 2
3 Available 5 2
4 Delivered 5 2
5 Delivered 5 3
6 Delivered 6 2
I want to group by each Driver and Trip with an extra column displaying the count of the OrderStatus when it is equal to 'Available'. So, for example
TotalOrderCountInTrip DriverId TripId AvailableOrdersCount
--------------------- -------- ------ --------------------
4 5 2 3
1 6 2 0
I've gotten this far but I can't figure out how to add the AvailableOrdersCount column:
select count(*) TotalOrderCountInTrip, dos.DriverId, dos.TripId
from DriverOrderSet dos (nolock)
group by
dos.DriverId,
dos.TripId
Add as a column:
sum(case when OrderStatus = 'Available' then 1 else 0 end)

SQL Stored Procedures : Count, Join and group by but it is shown 'NULL'

I got stuck something about stored procedures I write a stored that i need to shot three columns of products count like this
SELECT
Count([TPDTN].[ProductName]) as 'Product Count',
[TPDTN].[CategoryID]
FROM
[TPDTN]
LEFT JOIN
[TPDCN] ON [TPDTN].[CategoryID] = [TPDCN].[libDocumentID]
GROUP BY
[TPDTN].[CategoryID], [TPDCN].[libDocumentID]
It shows results like this:
Product Count CategoryID
---------------------------
2 1
9 2
2 3
2 4
1 5
But I don't know how make it show
Product Count CategoryID libDocumentID
-----------------------------------------------
2 1 123456789
9 2 123456789
2 3 123456789
2 4 123456789
1 5 123456789
Producer ID (LibdocumentID) is from other table but when I SELECT [TPDCN].[libDocumentID] the value is NULL
Product Count CategoryID libDocumentID
------------------------------------------------
2 1 NULL
9 2 NULL
2 3 NULL
2 4 NULL
1 5 NULL
How can I solve it? Thank you
Just add it to the select, and if you don't need the NULL you need an INNER JOIN:
SELECT Count([TPDTN].[ProductName]) as 'Product Count',[TPDTN].[CategoryID], [TPDCN].[libDocumentID]
FROM [TPDTN]
inner join [TPDCN]
ON [TPDTN].[CategoryID] = [TPDCN].[libDocumentID]
GROUP BY [TPDTN].[CategoryID],[TPDCN].[libDocumentID]

Computing a field to identify chronological order of datapoints that share the same ID

I using Microsoft SQL Server 2008 to try and identify the chronological order of data points in order to create a filter field that will allow me to create a query that only includes the first and last record for each ID number, where multiple rows represent different data points from the same ID
Here is an example of my current data and desired data to give a better idea of what I mean:
Current Data
ID Indicator Date
1 1 1988-02-11
1 1 1989-03-9
1 1 1993-04-3
1 1 2001-05-4
2 1 2000-01-01
2 1 2001-02-03
2 1 2002-04-22
3 1 1990-02-01
3 1 1998-02-01
3 1 1999-03-02
3 1 2000-04-02
4 0 NA
Desired Data
ID Indicator Date Order_Indicator
1 1 1988-02-11 1
1 1 1989-03-9 2
1 1 1993-04-3 3
1 1 2001-05-4 4
2 1 2000-01-01 1
2 1 2001-02-03 2
2 1 2002-04-22 3
3 1 1990-02-01 1
3 1 1998-02-01 2
3 1 1999-03-02 3
3 1 2000-04-02 4
4 0 NULL NULL
The field I want to create is the "Order_Indicator" field in the "Desired Data" table and with the only relevant records are records with Indicator = 1. With this information I would create a query where I only select the rows where Order_Indicator = 1 and Order_Indicator = MAX(Order_Indicator) for each "row group" that share the same ID. Does anyone have any idea about how I might go about this? I know I could do this very easily in Excel but I need to do it on SQL server in order for it to be reproducible with my colleagues.
Thank you so much in advance!
You can do this with the ranking functions:
select c.*,
(case when indicator = 1
then row_number() over (partition by id, indicator order by [date])
end) as OrderIndicator
from current c
This assigns a sequential number based on the date and indicator. The case statement takes care of the indicator = 0 case.
By the way, this assumes that "date" is being stored as a date.
Use below query :
select YourTable.ID,
YourTable.indicator,
case when date<>'NA' then date end as date,
case when indicator = 1 then row_number() over (partition by id, indicator order by ID) end as Order_Indicator
from YourTable

Resources