Problems joining several tables - sql-server

I always look for the solution but today I surrender so please I need help.
I am using two 'inner join' because I need to get the sum of balances from two tables, but the command 'inner join ' doubles the valor when I use sum(column 1, column 2), while that when I use sum(Column 1) everything is ok.
For example:
this query work very well, but I also have to query from other table called casilleros.
select datos_usuarios.id_cliente,
datos_usuarios.nombre ,
sum(membresia.saldo)
from datos_usuarios
inner join membresiaondatos_usuarios.id_cliente=membresia.id_socio
where saldo>0
group by datos_usuarios.id_cliente, datos_usuarios.nombre
I had tried many thing for example
select datos_usuarios.id_cliente,
datos_usuarios.nombre,
sum(membresia.saldo+casilleros.saldo)
from datos_usuarios
inner join membresia on datos_usuarios.id_cliente=membresia.id_socio
inner join casilleros on datos_usuarios.id_cliente=casilleros.id_socio
group by datos_usuarios.id_cliente, datos_usuarios.nombre
But the result is wrong.
I tried with 'union all' but honestly It is not that I need.Because I need only one result of balance per client

select t0.id_cliente,
t0.nombre,
cast(sum(t1.saldo) + sum(t2.saldo) as decimal (10,2)),
from datos_usuarios t0
inner join membresia t1 on t0.id_cliente=t1.id_socio
inner join casilleros t2 on t0.id_cliente=t2.id_socio
group by t0.id_cliente, t0.nombre

UNION ALL is probably what you really want. But you want it as a derived table. Then do the sum in the outer query.
Select a.id_cliente, a.nombre, sum(a.saldo)
From
(select datos_usuarios.id_cliente, datos_usuarios.nombre, membresia.saldo from
datos_usuarios
inner join membresia on datos_usuarios.id_cliente=membresia.id_socio
inner join casilleros on datos_usuarios.id_cliente=casilleros.id_socio
UNion all
select datos_usuarios.id_cliente, datos_usuarios.nombre, casilleros.saldo from
datos_usuarios
inner join casilleros on datos_usuarios.id_cliente=casilleros.id_socio
) a
group by a.id_cliente, a.nombre

I think you want to get this query
;WITH mc AS (
SELECT saldo, id_socio
FROM membresia
UNION
SELECT saldo, id_socio
FROM casilleros
)
SELECT
datos_usuarios.id_cliente,
datos_usuarios.nombre,
sum(mc.saldo)
FROM datos_usuarios
JOIN mc ON mc.id_socio = datos_usuarios.id_cliente
GROUP BY datos_usuarios.id_cliente, datos_usuarios.nombre
We union two tables with the same structure in one pseudo table mc (using CTE) and then join our new table with table datos_usuarios.

Related

SQL to find which table has diag_code filled, and then look it up in lookup_table

I have a query and a diag_code is either in one table (UM_SERVICE) or the other (LOS), but I can't join both tables to get diag_code that isn't null, that I can think of. Does this look ok for finding if diag_code is in one of the tables and lookup table? It's possible to have both LOS and UM_SERVICE have a diag code on different rows, and they could be different, and both or one could be in the lookup table. I'm not seeing anything in internet search.
Here's a simplified stored procedure:
SELECT distinct
c.id
,uc.id
,c.person_id
FROM dbo.CASES c
INNER JOIN dbo.UM_CASE uc with (NOLOCK) ON uc.case_id = c.id
LEFT JOIN dbo.UM_SERVICE sv (NOLOCK) ON sv.case_id = omc.case_id
LEFT JOIN dbo.UM_SERVICE_CERT usc on usc.service_id = sv.id
LEFT JOIN dbo.LOS S WITH (NOLOCK) ON S.case_id = UC.case_id
LEFT JOIN dbo.LOS_EXTENSION SC WITH (NOLOCK) ON SC.los_id = S.id
INNER JOIN dbo.PERSON op with (NOLOCK) on op.id = c.Person_id
WHERE
(sv.diag_code is not null and c.case_id = sv.case_id
or
s.diag_code is not null and c.case_id = s.case_id)
and
(sv.diag_code is not null and sv.diag_code in (select diag_code from TABLE_LOOKUP)
or
s.diag_code is not null and s.diag_code in (select diag_code from TABLE_LOOKUP)
Table setups like this:
CASES
id person_id
UM_CASE
case_id
LOS
case_id id
LOS_EXTENSION
los_id
Person
id cid
UM_SERVICE
case_id diag_code
UM_SERVICE_CERT
service_id id
TABLE_LOOKUP
diag_code
Since you have two different searches being run, it is going to be much easier to write/read by writing the searches individually and then bringing your two results sets together using the UNION operator. The UNION will eliminate duplicates across the two result sets in a similar manner to what your usage of SELECT DISTINCT is doing for a single result set.
Like so:
/*first part of union performs seach using filter on dbo.UM_SERVICE*/
SELECT
c.id
,uc.id
,c.person_id
FROM
dbo.CASES AS c
INNER JOIN dbo.UM_CASE AS uc ON uc.case_id=c.id
LEFT JOIN dbo.UM_SERVICE AS sv ON sv.case_id = omc.case_id
LEFT JOIN dbo.UM_SERVICE_CERT AS usc on usc.service_id=sv.id
LEFT JOIN dbo.LOS AS S ON S.case_id = UC.case_id
LEFT JOIN dbo.LOS_EXTENSION AS SC ON SC.los_id= S.id
INNER JOIN dbo.PERSON AS op on op.id=c.Person_id
WHERE
sv.diag_code in (select diag_code from TABLE_LOOKUP) /*will eliminate null values in sv.diag_code*/
UNION /*deduplicate result sets*/
/*second part of union performs search using filter on dbo.LOS*/
SELECT
c.id
,uc.id
,c.person_id
FROM
dbo.CASES AS c
INNER JOIN dbo.UM_CASE AS uc ON uc.case_id=c.id
LEFT JOIN dbo.UM_SERVICE AS sv ON sv.case_id = omc.case_id
LEFT JOIN dbo.UM_SERVICE_CERT AS usc on usc.service_id=sv.id
LEFT JOIN dbo.LOS AS S ON S.case_id = UC.case_id
LEFT JOIN dbo.LOS_EXTENSION AS SC ON SC.los_id= S.id
INNER JOIN dbo.PERSON AS op on op.id=c.Person_id
WHERE
s.diag_code in (select diag_code from TABLE_LOOKUP); /*will eliminate null values in s.diag_code*/

I need to make select inside another select (sql server)

in the select statement below I have 707 row
select detail_serial, Price from apa_invoice_detail
and I have another select statement which is
Select max(detail_serial)
,asc_item.item_name_2
,asc_group.group_name_2
From apa_invoice_detail
inner join asc_item on asc_item.item_id=apa_invoice_detail.item_id
inner join asc_group on asc_group.group_id=asc_item.group_id
Group by asc_item.item_name_2, asc_group.group_name_2
and this one gives me 197 row
I need to get the price from the first statement for the detail_serial in the second statement (for only 197 row)
I tried this:
select detail_serial, Price from apa_invoice_detail where detail_serial in
(Select max(detail_serial)
,asc_item.item_name_2
,asc_group.group_name_2
From apa_invoice_detail
inner join asc_item on asc_item.item_id=apa_invoice_detail.item_id
inner join asc_group on asc_group.group_id=asc_item.group_id
Group by asc_item.item_name_2, asc_group.group_name_2)
but it gives me "Only one expression can be specified in the select list when the subquery is not introduced with EXISTS."
How can I solve this ???
try removing the columns in the inner select statement
select detail_serial, Price from apa_invoice_detail where detail_serial in
(Select max(detail_serial)
From apa_invoice_detail
inner join asc_item on asc_item.item_id=apa_invoice_detail.item_id
inner join asc_group on asc_group.group_id=asc_item.group_id
Group by asc_item.item_name_2, asc_group.group_name_2)
Use EXISTS instead of IN.
;WITH SecondQueryResults AS
(
Select max(detail_serial) detail_serial
, asc_item.item_name_2
, asc_group.group_name_2
From apa_invoice_detail
inner join asc_item on asc_item.item_id=apa_invoice_detail.item_id
inner join asc_group on asc_group.group_id=asc_item.group_id
Group by asc_item.item_name_2, asc_group.group_name_2
)
select
detail_serial,
Price
from
apa_invoice_detail T
where
EXISTS (SELECT 'serial exists on query result' FROM SecondQueryResults AS S WHERE S.detail_serial = T.detail_serial)
... or just select 1 column (the detail_serial) inside your IN subquery.

replace nested where condition with join

I have a SQL query that looks like this
Select a.*
From table1 a
where a.ColumnName in
(Select MAX(b.ColumnName)
from table2 b
where b.ColumnName2 in
(
Select MAX(c.columnName)
from table3 c
Group by c.ColumnName2
)
Group by b.ColumnName2
)
I am trying to write this in a join statement. I am positive inner join is what I need to get the right information. If someone could translate this to a join statement, I would be really glad.
Thank you.
EDIT 1:
I tried the typical Join statement that a rookie would.
Select a.*
from table1 a
inner join table2 b
on a.columnname = (Select max(b.columnName) from table2)
inner join table3 c
on b.columnName = (select max(c.columnName) from table3)
Obviously, that didn't work because I get 100,000+ results when I should be getting 800. I tried using an alias for table2 and table3 INSIDE the subselect statements and selecting the columnname using THAT alias like this:
Select max(bPart.columnName from table2 bPart)
Select max(cPart.columnName from table3 cPart)
Still the same result.
PERHAPS....
Though I'm not sure why a join is needed. Performance wise exists would likely be fastest, and since you're not returning values from table2 or 3 it seems like it would be the best approach.
SELECT a.*
FROM table1 a
INNER JOIN (SELECT MAX(ColumnName) MColumnName, columnname2
FROM table2
GROUP BY columnName2) B
ON A.columnName = B.mColumnName
INNER JOIN (SELECT MAX(columnName) mColumnName
FROM table3
GROUP BY ColumnName2) C
ON B.columname2 = C.MColumnName

SQL UNION INNER JOIN

Im trying to select from 2 tables that have the same columns, but both tables have an inner join -
select e.ID,
c.FullName,
car.VIN,
car.Registration,
e.Telephone,
e.Mobile,
e.Email,
e.EstimateTotal,
e.LastUpdated,
e.LastUpdateBy from (select id from Estimates UNION ALL select id from PrivateEstimates) e
inner join Customers c on c.ID = e.CustomerID
inner join Cars car on car.ID = e.CarID
where e.Status = 0
The trouble is, it can't find e.CustomerID, e.CarID or e.Status on the inner join? Any ideas?
Your subquery
select id from Estimates
union all
select id from PrivateEstimates
returns only a single id column. Include necessary columns in the subquery if you want to use those columns in JOIN statements

Stored procedure inner join

My first stored procedure (in sql-server). I'm not able to make it work, it raises a warning in a.Id
After reading, and not really understand much, I'm not even sure if I can use this inner join inside a stored procedure.
select top 1 b.*, a.*
FROM Bids b
INNER JOIN Auctions a
ON b.Auction_Id = a.Id
(NOLOCK) WHERE ( a.Ends IS NOT NULL AND a.Starts IS NOT NULL AND a.Starts < #Now AND a.Ends > #Now)
ORDER BY b.CreationTime DESC
Actually, I'll need just b.* but I assume I have to retrieve all the fields?.
Thanks
Change the locking hint to this:
INNER JOIN Auctions a WITH(NOLOCK)
Full query would be:
select top 1 b.*, a.*
FROM Bids b
JOIN Auctions a WITH(NOLOCK) ON b.Auction_Id = a.Id
WHERE ( a.Ends IS NOT NULL
AND a.Starts IS NOT NULL
AND a.Starts < #Now
AND a.Ends > #Now)
ORDER BY b.CreationTime DESC
Take the (Nolock) out, or put it after the table name if you need it.
You can use Select to select any fields you want from any table in your query.

Resources