How to retrieve only a single row - tsql

Shown below is part of the view view_ar_rate_detail. I am trying to retrieve the 'daily_pay_rate' having 'eff_date_from' just prior to or equal to '2018-10-01'
The query shown below retrieves all rows ... I am missing something ...cant figure out what
fac_id eff_date_from daily_pay_rate
3 1/1/2018 195.03
3 11/1/2017 195.03
3 9/1/2017 195.03
3 8/1/2017 198.23
3 2/1/2017 198.23
3 9/1/2016 198.23
3 9/1/2015 197.43
3 2/1/2015 197.43
SELECT fac_id,eff_date_from,daily_pay_rate
FROM [view_ar_rate_detail] D
where fac_id = 3
and care_level = 'RAD'
and revenue_code = 100
and payer_id = 3
and rate_type_id = 2
and eff_date_from =
(select top 1 eff_date_from
[view_ar_rate_detail]
where fac_id = D.Fac_id
and care_level = D.care_level
and revenue_code = D.revenue_code
and payer_id = D.payer_id
and rate_type_id = D.rate_type_id
and eff_date_from <= '2018-10-01'
order by eff_date_from desc)

Please disregard. I got it to work. When working with the entire view, there were a couple of fields that had to be joined to make the query unique.

Related

Update query to update values incrementally and then loop PostgreSQL

I am trying to write a query which will update the following below:
id = 1 --> id_scraping_account = 1
id = 2 --> id_scraping_account = 2
id = 3 --> id_scraping_account = 3
id = 4 --> id_scraping_account = 1
id = 5 --> id_scraping_account = 2
id = 6 --> id_scraping_account = 3
The main thing I am trying to understand is the structure of the query
You can do:
select id, id%3 as id_scraping_account
from your_table;
#PabloSantaCruz - almost. That however gives the resulting sequence 1,2,0. Should be:
select id, ((id-1)%3)+1 id_scraping_account
from your_table;

T SQL Conditional join

forgive my language, English is not my mother tongue.
The following scenario exists:
An object, let's call it an apartment for simplicity, can (but does not have to) refer to a parent object of the same type that we now call house.
The apartment may have an address (other table), if not the address of the house is relevant.
For this I try to build a join, which returns either the address of the apartment (if available), or the address of the house.
My previous approach:
LEFT OUTER JOIN
dbo.stelle_adressen AS ADR_Default ON
(ADR_Default.stelle_id = stelle.stelle_id
AND ADR_Default.adress_typ_id = 1
AND ADR_Default.aktiv = 1)
OR
(ADR_Default.stelle_id = stelle.referenz_id
AND ADR_Default.adress_typ_id = 1
AND ADR_Default.aktiv = 1)
Also works, just not as needed, because if a housing address is present, also the join to the house address is formed, and therefore 2 lines are delivered as a result.
Any advice?
Simplified Query:
SELECT
stelle.stelle_id,
ADR_DOBJ.adr_objekt_id,
ADR_STR.strasse,
ADR_STR.plz,
ADR_STR.ort,
ADR_DOBJ.hausnummer,
ADR_Default.aktiv
FROM
stelle
INNER JOIN
stelle_adressen AS ADR_Default ON
(ADR_Default.stelle_id = stelle.stelle_id AND ADR_Default.adress_typ_id = 1 AND ADR_Default.aktiv = 1)
OR
(ADR_Default.stelle_id = stelle.referenz_id AND ADR_Default.adress_typ_id = 1 AND ADR_Default.aktiv = 1)
LEFT OUTER JOIN
adr_objekt AS ADR_DOBJ ON ADR_DOBJ.adr_objekt_id = ADR_Default.adr_objekt_id
LEFT OUTER JOIN
adr_objekt_strassen AS ADR_STR ON ADR_STR.strasse_id = ADR_DOBJ.strasse_id
WHERE stelle.stelle_id = 2
Result:
stelle_id adr_objekt_id strasse plz ort hausnummer aktiv
2 8 Walterhöferstraße 14165 Berlin 11 1
2 1 Gustav-Adolf-Straße 13086 Berlin 106a 1
Expected Result:
stelle_id adr_objekt_id strasse plz ort hausnummer aktiv
2 8 Walterhöferstraße 14165 Berlin 11 1
The query return 2 rows, one with own adress, one with adress of refered object adress (which should only be returned if no own adress is available)
As variant you can try to use TOP 1 with ORDER BY
SELECT TOP 1
stelle.stelle_id,
ADR_DOBJ.adr_objekt_id,
ADR_STR.strasse,
ADR_STR.plz,
ADR_STR.ort,
ADR_DOBJ.hausnummer,
ADR_Default.aktiv
FROM stelle
JOIN stelle_adressen AS ADR_Default ON
ADR_Default.adress_typ_id = 1 AND ADR_Default.aktiv = 1
AND (ADR_Default.stelle_id = stelle.stelle_id OR ADR_Default.stelle_id = stelle.referenz_id)
LEFT JOIN
adr_objekt AS ADR_DOBJ ON ADR_DOBJ.adr_objekt_id = ADR_Default.adr_objekt_id
LEFT JOIN
adr_objekt_strassen AS ADR_STR ON ADR_STR.strasse_id = ADR_DOBJ.strasse_id
WHERE stelle.stelle_id = 2
ORDER BY IIF(ADR_Default.stelle_id = stelle.referenz_id,2,1)
The priority of stelle.stelle_id is 1, and stelle.referenz_id is 2.
Do you always want to get only one row?
Do the condition WHERE stelle.stelle_id = 2 use always?
If you want to get addresses for several stelle_id you can try the following
SELECT *
FROM
(
SELECT
stelle.stelle_id,
ADR_DOBJ.adr_objekt_id,
ADR_STR.strasse,
ADR_STR.plz,
ADR_STR.ort,
ADR_DOBJ.hausnummer,
ADR_Default.aktiv,
ROW_NUMBER()OVER(PARTITION BY stelle.stelle_id ORDER BY IIF(ADR_Default.stelle_id = stelle.referenz_id,2,1)) N
FROM stelle
JOIN stelle_adressen AS ADR_Default ON
ADR_Default.adress_typ_id = 1 AND ADR_Default.aktiv = 1
AND (ADR_Default.stelle_id = stelle.stelle_id OR ADR_Default.stelle_id = stelle.referenz_id)
LEFT JOIN
adr_objekt AS ADR_DOBJ ON ADR_DOBJ.adr_objekt_id = ADR_Default.adr_objekt_id
LEFT JOIN
adr_objekt_strassen AS ADR_STR ON ADR_STR.strasse_id = ADR_DOBJ.strasse_id
--WHERE stelle.stelle_id = 2
) q
WHERE N=1
I've commented the condition WHERE stelle.stelle_id = 2 here.
PS. I think you also can use condition AND ADR_Default.stelle_id IN(stelle.stelle_id,stelle.referenz_id) instead AND (ADR_Default.stelle_id = stelle.stelle_id OR ADR_Default.stelle_id = stelle.referenz_id).

How to sum items from subtable in SQL

Let's say I have table orders
id name
1 order1
2 order2
3 order3
and subtable items
id parent amount price
1 1 1 10
2 1 3 20
3 2 2 5
4 2 5 1
I would like to create query with order with added column value. it should calculate order with all relevant items
id name value
1 order1 70
2 order2 15
3 order3 0
Is this possible with TSQL
GROUP BY and SUM would do it, need to use left join and isnull as you don't have items for all orders.
SELECT o.id, o.name, isnull(sum(i.amount*i.price),0) as value
FROM orders o
left join items i
on o.id = i.parent
group by o.id, o.name
I think you're looking for something like this
SELECT o.name, i.Value FROM orders o WITH (NOLOCK)
LEFT JOIN (SELECT parent, SUM(price) AS Value FROM items WITH (NOLOCK) GROUP BY parent) i
ON o.id = i.parent
...seems like RADAR beat me to the answer.
EDIT: missing the ON line.

How to determine whether a value exists in a junction table and return zero or one?

I am using SQL Server 2008 R2
I am trying to write a single query that will return only exactly what I need. I will drop in a MovieID and get back a list of ALL genres. If the movie represents a specific genre (has an associated record in the junction table), the Checked value will be 1. If not, then 0.
My result set should look like this:
GenreID Genre Checked
1 ABC 0
2 DEF 1
3 HIJ 0
4 KLM 1
My First table is named Genres. It looks like this:
GenreID Genre
1 ABC
2 DEF
3 HIJ
4 KLM
My second table is named Movies. It looks like this:
MovieID Title
1 Blah
2 Foo
3 Carpe
4 Diem
My third table is a junction table named Movies_Genres. It looks like this:
MovieID GenreID
1 2
1 1
1 4
2 1
2 3
3 4
4 1
I would normally, do a couple of queries and a couple of loops to handle this, but I want to really just make the database do the work here. How do I tweak my query so that I can get the resultset that I need with just a single query?
Here's the starting query:
SELECT GenreID,
Genre
FROM Genres
Thanks in advance for your help!!!
SELECT g.GenreID, g.Genre, Checked = CASE WHEN EXISTS
(SELECT 1 FROM dbo.Movies_Genres AS mg
INNER JOIN dbo.Movies AS m
ON mg.MovieID = m.MovieID
WHERE mg.GenreID = g.GenreID
AND m.MovieID = #MovieID) THEN 1 ELSE 0 END
FROM dbo.Genres AS g
ORDER BY g.GenreID;
If there is a unique constraint or primary key on dbo.Movies_Genres(MovieID, GenreID) then this can be simply:
SELECT g.GenreID, g.Genre, Checked = COUNT(mg.GenreID)
FROM dbo.Genres AS g
LEFT OUTER JOIN dbo.Movies_Genres AS mg
ON g.GenreID = mg.GenreID
AND mg.MovieID = #MovieID
GROUP BY g.GenreID, g.Genre;
...since the count for any genre can only be 0 or 1 given a single #MovieID.
Pretty straight forward using CASE;
SELECT DISTINCT g.GenreID, g.Genre,
CASE WHEN mg.MovieID IS NULL THEN 0 ELSE 1 END Checked
FROM Genres g
LEFT JOIN Movies_Genres mg
ON g.GenreID=mg.GenreID
AND mg.MovieId=#MovieID;
Demo here.
Edit: If entries are guaranteed to be unique in Movies_Genres, you could choose to drop the DISTINCT.
The #MovieID is the movie, you want to filter by.
SELECT Genres.GenreID,
Genres.Genre,
CASE WHEN (Movies_Genres.GenreID IS NULL)
THEN 0
ELSE 1
END AS Checked
FROM Genres LEFT JOIN
Movies_Genres ON Movies_Genres.GenreID = Genres.GenreID AND
MovieID = #MovieID

SQL select from a group

Suppose we have the following table data:
ID parent stage submitted
1 1 1 1
2 1 2 1
3 1 3 0
4 1 4 0
5 5 1 1
6 5 2 1
7 5 3 1
8 5 4 1
As you can see we have 2 groups (that have the same parent). I want to select the latter stage that is submitted. In the above example i want to select the ID`s 2 and 8. I am completely lost so if anyone can help it will be appreciated a lot. :)
SELECT T.ID, T.PARENT, T.STAGE
from
T,
(
select PARENT, MAX( STAGE) MAX_STAGE
from T
where SUBMITTED = 1
GROUP BY PARENT
) M
where
T.STAGE = M.MAX_STAGE
AND T.PARENT = M.PARENT
Explanation:
First, isolate the max stage for each group with submitted = 1 (the inner select).
Then, join the result with the real table, to filter out the records with no max stage.
Select Parent, max(Id)
From tbl t
Inner Join
(
Select Parent, max(Stage) as Stage
from tbl t
Where Submitted = 1
Group by Parent
) submitted
on t.Parent = submitted.parent and
t.stage = submitted.stage
Group by Parent
This should do it:
SELECT
T1.id,
T1.parent,
T1.stage,
T1.submitted
FROM
Some_Table T1
LEFT OUTER JOIN Some_Table T2 ON
T2.parent = T1.parent AND
T2.submitted = 1 AND
T2.stage > T1.stage
WHERE
T1.submitted = 1 AND
T2.id IS NULL
SELECT * FROM Table WHERE ID = 2 OR ID = 8
Is this what you want?