OPTIMIZING LEFT JOIN in SQL SERVER - sql-server

SELECT h.*
FROM h
LEFT JOIN au ON au.ID = h.Key AND au.RaID = 40190 AND h.EntityType = 'Detail'
LEFT JOIN ip ON ip.ID = h.Key AND ip.RaID = 40190 AND h.EntityType = 'itempart'
WHERE
coalesce(au.id,ip.id) is not null
Anyone have a good idea how to optimize this? h is HUGE history log table.

what about using a union on your allowed types then you can use an inner join:
SELECT h.*
FROM h
INNER JOIN (
SELECT ID, 'Detail' AS EntityType FROM au WHERE (RaID = 40190)
UNION ALL
SELECT ID, 'itempart' AS EntityType FROM ip WHERE (RaID = 40190)
) AS filt
ON h.Key = filt.ID
AND h.EntityType = filt.EntityType
also make sure you have indexes on your filtered/joined columns. And as always when looking for performance issues check the query plan as n8wrl suggests above.

Related

Azure SQL STRING_AGG as part of larger Query

Many questions/solutions I've read here describe how to use STRING_AGG by itself and I can get the following to work:
SELECT Offers.Id, STRING_AGG ( Offers2Currencies.CurrencyCode, ', ' ) AS Currencies
FROM Offers INNER JOIN Offers2Currencies ON Offers2Currencies.OfferID =
dbo.Offers.ID
WHERE dbo.Offers.BuyerMemberId = '64ad10b9-85a6-4fc4-b9eb-d9f9af164d2b'
GROUP BY dbo.Offers.Id
But I am struggling with how to put that inside a larger query such as:
SELECT
dbo.Offers.ID,
dbo.Offers.UTC,
dbo.Organizations.Code,
dbo.Entities.EntityAbbrev,
dbo.Measurables.Name,
dbo.Offers.Price,
dbo.Offers.SellerMemberId,
dbo.AspNetUsers.UserName
--select STRING_AGG(dbo.Offers2Currencies.CurrencyCode, ', ') Currencies
FROM dbo.Offers
INNER JOIN dbo.AspNetUsers ON dbo.AspNetUsers.Id = dbo.Offers.SellerMemberId
INNER JOIN dbo.MemberCreditRatings ON dbo.AspNetUsers.Id = dbo.MemberCreditRatings.MemberGUID
INNER JOIN dbo.Measurables ON dbo.Offers.MeasurableID = dbo.Measurables.ID
INNER JOIN dbo.Entities ON dbo.Offers.EntityID = dbo.Entities.ID
INNER JOIN dbo.Organizations ON dbo.Measurables.OrganizationID = dbo.Organizations.ID
--INNER JOIN dbo.Offers2Currencies ON dbo.Offers2Currencies.OfferID = dbo.Offers.ID
AND dbo.Entities.OrganizationID = dbo.Organizations.ID
WHERE dbo.Offers.BuyerMemberId = '64ad10b9-85a6-4fc4-b9eb-d9f9af164d2b'
I (think) I figured it out -- put all fields being selected into the Group By (though they never get accessed beyond the first group by) -- see http://sqlfiddle.com/#!18/aaa65/7 (and advise if better or alternative solution)

Structured query language Join query

I am new to SQL.Is this a correct join for multiple tables.
select * from [dbo].[Quotes] Q ,[dbo].[Invoices] I ,[dbo].[Receipts] R ,
[dbo].[QuoteLines] QL where QL.QuoteID = Q.ID AND I.QuoteID = Q.ID
AND R.QuoteID = Q.ID AND QL.Amount = 336.47 and QL.TravelType = 'International' and QL.Type = 'Accommodation'
Your question
Is this a correct join for multiple tables
Should be answered with No... It might work as expected, but this way of joining is outdated for centuries.
Your approach names all tables comma separated. This would lead to a huge cartesian product, a combination of each row with each row. The following WHERE clause makes sure, that you will get the needed/related rows and columns only...
Not knowing your structure this is a blind flight, but I think you are looking for something like this:
select *
from [dbo].[Quotes] Q
inner join [dbo].[QuoteLines] QL on Q.ID=QL.QuoteID
inner join [dbo].[Invoices] I on I.QuoteID=Q.ID
inner join [dbo].[Receipts] R on R.QuoteID=Q.ID
where QL.Amount = 336.47
and QL.TravelType = 'International'
and QL.[Type] = 'Accommodation';
You might want to change inner to left in cases, where not each row has a corresponding row on the other side.
Try this:-
Select table1.ID ,table1.Name
from Table1
inner join Table2 on Table1 .ID =Table2 .ID
inner join Table3 on table2.ID=Table3 .ID
where table1.Name = Table3.Name

SQL Server 2008: Only one result, joining 3 tables

I have the following databases:
IMAGE UPDATED
SELECT
l.FECHA, nc.IdNumeroControlTrabajador AS ENLACE,
t.RFC, t.Homonimia AS HOM,
t.ApellidoPaterno, t.ApellidoMaterno,
t.Nombre, l.IMPORTE,
cp.NombreOrgano AS DEPENDENCIA, l.OBSERVACIONES,
l.FECHA_INICIAL, l.FECHA_FINAL,
MAX (cn.FechaIngresoGobierno)
FROM
CapturaFAIFAP.dbo.Laudos AS l
LEFT JOIN FAIFAPparalelo.dbo.NumeroControlTrabajadores AS nc ON l.ID = nc.idTrabajador
LEFT JOIN FAIFAPparalelo.dbo.ClaveNominalTrabajadores AS cn ON l.ID = cn.idTrabajador
LEFT JOIN FAIFAPparalelo.dbo.Trabajadores AS t ON l.ID = t.idTrabajador
LEFT JOIN FAIFAPparalelo.dbo.ClaveProgramatica AS cp ON cn.idClaveProgramatica = cp.idClaveProgramatica
LEFT JOIN (
SELECT
cp.NombreOrgano,
MAX (cnt.FechaIngresoGobierno) AS fecha
FROM
FAIFAPparalelo.dbo.ClaveNominalTrabajadores as cnt
GROUP BY
cp.NombreOrgano
) AS j ON (
cp.NombreOrgano = j.NombreOrgano
AND j.fecha = cn.FechaIngresoGobierno
)
GROUP BY
l.FECHA, nc.IdNumeroControlTrabajador, t.RFC,
t.Homonimia, t.ApellidoPaterno, t.ApellidoMaterno,
t.Nombre,l.IMPORTE,cp.NombreOrgano,l.OBSERVACIONES,
l.FECHA_INICIAL,l.FECHA_FINAL,cn.FechaIngresoGobierno
I need to unify the query. The huge query i put in code, and a similar query in the image. If i join the tables ClaveNominal and ClaveProgramatica i have duplicities, because sometimes the persons have 2 ClavesProgramaticas, due to the system I use, not delete or update the current registry, just puts in inactive and adds a new one active, and i can't make the condition to activo because, that represents if the person still works here.

Any other ways to change "With As" for mariadb

WITH KPILibHier (kpilib_code,parent_code,kpi_name, depth, iscategory)
AS ( SELECT K.kpilib_code, K.parent_code, K.kpi_name_en, K.kpi_depth, K.iscategory
FROM TPMDPERIODKPILIB K
INNER JOIN TPMDPERIODKPI PK ON PK.period_code = K.period_code
UNION ALL
SELECT A.kpilib_code, A.parent_code, A.kpi_name_en, A.kpi_depth, A.iscategory
FROM TPMDPERIODKPILIB A
INNER JOIN KPILibHier AS B ON A.kpilib_code = B.parent_code )
SELECT DISTINCT Z.kpi_name AS libname, Z.kpilib_code AS libcode,
Z.parent_code AS pcode, Z.depth, Z.iscategory, PK.target
FROM KPILibHier Z
LEFT JOIN TPMDPERIODKPILIB KPI
ON KPI.kpilib_code = Z.kpilib_code
LEFT JOIN TPMDPERIODKPI PK
ON PK.period_code = KPI.period_code
ORDER BY Z.depth, Z.kpi_name
This is my code.
I could run it in SQL Server,
But now i have to use Mariadb,
and Mariadb doesn't use "WITH AS".
So is there any other way to change this code for the same result?
As we can see, there's "INNER JOIN KPILibHier" too inside the CTE,
So I couldn't make ordinary subquery as usual.
Just moving the contents of the CTE to a derived table should provide something usable. Something like;
SELECT DISTINCT Z.kpi_name AS libname, Z.kpilib_code AS libcode,
Z.parent_code AS pcode, Z.depth, Z.iscategory, PK.target
FROM
( SELECT K.kpilib_code, K.parent_code, K.kpi_name_en AS kpi_name, K.kpi_depth AS depth, K.iscategory
FROM TPMDPERIODKPILIB K
INNER JOIN TPMDPERIODKPI PK ON PK.period_code = K.period_code
UNION ALL
SELECT A.kpilib_code, A.parent_code, A.kpi_name_en, A.kpi_depth, A.iscategory
FROM TPMDPERIODKPILIB A
) z
INNER JOIN z AS B ON A.kpilib_code = B.parent_code
LEFT JOIN TPMDPERIODKPILIB KPI
ON KPI.kpilib_code = Z.kpilib_code
LEFT JOIN TPMDPERIODKPI PK
ON PK.period_code = KPI.period_code
ORDER BY Z.depth, Z.kpi_name

Join for more than one table

I have a mssql database name Organization
I have 3 tables:
Table 1 named Organization
Table 2 named Product
Table 3 named IPAddress
Table 1 returns about 1000 results which is fine.
SELECT distinct OrganizationName, AssetNumber
FROM OrganizationList
Where OrganizationName = 'orgname'
All I would like to see is the asset numbers with each org. Im not sure how to do this. I know a need a join and have tried a bunch of examples from the net however am not able to get it working.
Also I would like to be able to get the IPaddress for each asset
The problem i an running into is i need to match the OrganizationID col from Organization with the OrganizationID col from Product and i need to match the ProductId from Product and the ProductId from IPAddress
Any help would be greatly appreciated. Please let me know if you will need any more info.
Thank You
Should also list out the IP address for you as well.
SELECT distinct c1.OrganizationName, c2.AssetNumber, c3.IPAddress
FROM Organization c1
INNER JOIN Product c2
ON c1.OrganizationID = c2.OrganizationID
INNER JOIN IPAddress c3
ON c2.ProductId = c3.ProductId
Where c1.OrganizationName = 'orgname'
I am doing some guessing here since you didn't give us all of the information needed to fully help you. How about the following query:
SELECT DISTINCT o.OrganizationName, p.AssetNumber, ip.IPaddress
FROM Organization AS o
INNER JOIN Product AS p
ON o.OrganizationID = p.OrganizationID
INNER JOIN IPAddress AS ip
ON p.ProductId = ip.ProductId
Where o.OrganizationName = 'orgname'
I didn't see any need to join the OrganizationList table. If you do indeed need it then add the following join:
INNER JOIN OrganizationList AS ol
ON o.OrganizationID = ol.OrganizationID
for user3022598
Take result of this query in a temp table:
SELECT distinct o.OrganizationName, p.AssetNumber, i.IPAddress
FROM Organization o
INNER JOIN Product p
ON o.OrganizationID = p.OrganizationID
INNER JOIN IPAddress i
ON p.ProductId = i.ProductId
Where o.OrganizationName = 'orgname'
then you can apply disctint on ipaddress field.
Try this one:
select o.OrgName, o.AssetNo
from OrgList o
join Prdct p
on o.orgid = p.orgid
Union All
select p.productid/name, i.ipadress
from product p
join ipadres i
on p.prdid=i.prdid
Plz check it & let me know if works or not.

Resources