SQL select joined 2 tables same as one column - sql-server

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

Related

T-SQL select rows where [col] = MIN([col])

I have a data set produced from a UNION query that aggregates data from 2 sources.
I want to select that data based on whether or not data was found in only of those sources,or both.
The data relevant parts of the set looks like this, there are a number of other columns:
row
preference
group
position
1
1
111
1
2
1
111
2
3
1
111
3
4
1
135
1
5
1
135
2
6
1
135
3
7
2
111
1
8
2
135
1
The [preference] column combined with the [group] column is what I'm trying to filter on, I want to return all the rows that have the same [preference] as the MIN([preference]) for each [group]
The desired output given the data above would be rows 1 -> 6
The [preference] column indicates the original source of the data in the UNION query so a legitimate data set could look like:
row
preference
group
position
1
1
111
1
2
1
111
2
3
1
111
3
4
2
111
1
5
2
135
1
In which case the desired output would be rows 1,2,3, & 5
What I can't work out is how to do (not real code):
SELECT * WHERE [preference] = MIN([preference]) PARTITION BY [group]
One way to do this is using RANK:
SELECT row
, preference
, [group]
, position
FROM (
SELECT row
, preference
, [group]
, position
, RANK() OVER (PARTITION BY [group] ORDER BY preference) AS seq
FROM t) t2
WHERE seq = 1
Demo here
Should by doable via simple inner join:
SELECT t1.*
FROM t AS t1
INNER JOIN (SELECT [group], MIN(preference) AS preference
FROM t
GROUP BY [group]
) t2 ON t1.[group] = t2.[group]
AND t1.preference = t2.preference

Repeat a sum as a column in SQL

I have a table
WO# Seg# Part# QTY TotSale FlatSale
1 1 1 5 35 159
1 1 2 2 100 159
1 2 3 3 50 50
I need to calculate the FlatSale/SUM(TotSale) for each Seq# & WO# but do not group Seg# into one row.
I need this
WO# Seg# Part# QTY TotSale FlatSale Calc
1 1 1 5 35 159 1.177
1 1 2 2 100 159 1.177
1 2 3 3 50 50 1
With my code I am able to only do the division on each individual line like this:
select *, FlatSale/TotSale as Calc from table
WO# Seg# Part# QTY TotSale FlatSale Calc
1 1 1 5 35 159 4.54
1 1 2 2 100 159 1.59
1 2 3 3 50 50 1
I wouldn't mind leaving my Calc column and adding another column if that's the easiest way to do it.
Maybe something like this:
SELECT
[WO#],[Seg#],[Part#],[QTY],[TotSale],[FlatSale]
((FlatSale*100)/(SUM([TotSale]) OVER(PARTITION BY [Seg#] ORDER BY [Seg#])))/100 AS Calc
FROM SomeTable
You can use a lateral join. Here's something quick (not tested as I don't have access to mssql at the moment):
select *, x.CalcPrice as Calc
from table t
outer apply (
select t.FlatSale/SUM(ix.TotSale) CalcPrice
from table ix where ix.[WO#] = t.[WO#]
and ix.[Seg#] = t.[Seg#]) x
Something like that.

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 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]

Transact SQL - which Join to Use

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

Resources