SQL Where same as Join? - sql-server

I'm looking a SQL code and I'm not sure what it does.
This is the code:
SELECT *
FROM dba.spro_lotesfrutagranel,
dba.variedades,
dba.productores
WHERE ( dba.variedades.espe_codigo = dba.spro_lotesfrutagranel.lote_espcod ) and
( dba.variedades.vari_codigo = dba.spro_lotesfrutagranel.vari_codigo )
Does this the same as a left join? or not?
Thanks!

Don't use old style join! Use table aliases! You query should be rewriten like:
SELECT *
FROM dba.spro_lotesfrutagranel sl
INNER JOIN dba.variedades v
ON v.espe_codigo = sl.lote_espcod and
v.vari_codigo = sp.vari_codigo
INNER JOIN dba.productores p
ON p.somecolumn = ...
As for now your query is a Cartesian join with some where statement, all rows from spro_lotesfrutagranel and variedades are connected by two columns both and then with ALL rows from productores.
Note: I add two links with some explanation.

Related

Get specific columns from join without join syntax?

Is there another way to write this?
SELECT src.ID, factDeviceBuild.ID
FROM #factDeviceBuild as src
INNER JOIN AppsFlyer.FactDeviceBuild AS factDeviceBuild
ON src.[DimDevice_Id] = factDeviceBuild.[DimDevice_Id] AND
src.[DimDeviceModel_Id] = factDeviceBuild.[DimDeviceModel_Id] AND
src.[DimPlatform_Id] = factDeviceBuild.[DimPlatform_Id] AND
src.[DimOSVersion_Id] = factDeviceBuild.[DimOSVersion_Id] AND
src.[DimSDKVersion_Id] = factDeviceBuild.[DimSDKVersion_Id] AND
src.[DimCarrier_Id] = factDeviceBuild.[DimCarrier_Id] AND
src.[DimOperator_Id] = factDeviceBuild.[DimOperator_Id]
I've been trying to do some different things (that don't work) like this
SELECT *, factDeviceBuild.ID
FROM #factDeviceBuild
WHERE EXISTS (
SELECT [DimDevice_Id], [DimDeviceModel_Id], [DimPlatform_Id],
[DimOSVersion_Id], [DimSDKVersion_Id], [DimCarrier_Id],
[DimOperator_Id]
FROM AppsFlyer.FactDeviceBuild AS factDeviceBuild
)
or like this (also doesn't work):
SELECT factDeviceBuild.ID,
factDeviceBuild.[ID]
FROM (
SELECT [DimDevice_Id], [DimDeviceModel_Id], [DimPlatform_Id],
[DimOSVersion_Id], [DimSDKVersion_Id], [DimCarrier_Id],
[DimOperator_Id]
FROM AppsFlyer.FactDeviceBuild AS factDeviceBuild
INTERSECT
SELECT [DimDevice_Id], [DimDeviceModel_Id], [DimPlatform_Id],
[DimOSVersion_Id], [DimSDKVersion_Id], [DimCarrier_Id],
[DimOperator_Id]
FROM AppsFlyer.#factDeviceBuild AS factDeviceBuild
) AS A
I'm just playing around with some query tuning. EXCEPT and INTERSECT are particularly interesting because of the way they treat NULLS.
Obviously I could use a CROSS JOIN or OUTER JOIN to construct my INNER JOIN form scratch, but I don't see a particular gain there.
I believe you are looking for something like this:
SELECT src.ID, fact.ID
FROM #factDeviceBuild as src
INNER JOIN AppsFlyer.FactDeviceBuild AS fact
ON EXISTS (
SELECT src.DimDevice_Id, src.DimDeviceModel_Id, src.DimPlatform_Id,
src.DimOSVersion_Id, src.DimSDKVersion_Id, src.DimCarrier_Id,
src.DimOperator_Id
INTERSECT
SELECT fact.DimDevice_Id, fact.DimDeviceModel_Id, fact.DimPlatform_Id,
fact.DimOSVersion_Id, fact.DimSDKVersion_Id, fact.DimCarrier_Id,
fact.DimOperator_Id
)
Using this INTERSECT syntax (instead of the usual conditions) has the advantage of treating NULL-s as the same values. For example, if only the DimCarrier_Id and DimOperator_Id columns would allow NULL-s, the equivalent condition would need be:
SELECT src.ID, fact.ID
FROM #factDeviceBuild as src
INNER JOIN AppsFlyer.FactDeviceBuild AS fact
ON src.DimDevice_Id = fact.DimDevice_Id AND
src.DimDeviceModel_Id = fact.DimDeviceModel_Id AND
src.DimPlatform_Id = fact.DimPlatform_Id AND
src.DimOSVersion_Id = fact.DimOSVersion_Id AND
src.DimSDKVersion_Id = fact.DimSDKVersion_Id AND
(src.DimCarrier_Id = fact.DimCarrier_Id OR src.DimCarrier_Id IS NULL AND fact.DimCarrier_Id IS NULL) AND
(src.DimOperator_Id = fact.DimOperator_Id OR src.DimOperator_Id IS NULL AND fact.DimOperator_Id IS NULL)
Following is same
SELECT src.ID, factDeviceBuild.ID
FROM #factDeviceBuild as src, AppsFlyer.FactDeviceBuild AS factDeviceBuild
WHERE
src.[DimDevice_Id] = factDeviceBuild.[DimDevice_Id] AND
src.[DimDeviceModel_Id] = factDeviceBuild.[DimDeviceModel_Id] AND
src.[DimPlatform_Id] = factDeviceBuild.[DimPlatform_Id] AND
src.[DimOSVersion_Id] = factDeviceBuild.[DimOSVersion_Id] AND
src.[DimSDKVersion_Id] = factDeviceBuild.[DimSDKVersion_Id] AND
src.[DimCarrier_Id] = factDeviceBuild.[DimCarrier_Id] AND
src.[DimOperator_Id] = factDeviceBuild.[DimOperator_Id]
Without either data or a visualization of the expected result, my guess is you need to "unpivot" the 7 id types into less columns, which reduces the join syntax complexity. e.g.:
select
src.id, f.fact_id, ca.id_type, ca.id_value
from #factDeviceBuild as src
cross apply (
values
('DimDevice_Id',src.[DimDevice_Id])
,('DimDeviceModel_Id',src.[DimDeviceModel_Id])
,('DimPlatform_Id',src.[DimPlatform_Id])
,('DimOSVersion_Id',src.[DimOSVersion_Id])
,('DimSDKVersion_Id',src.[DimSDKVersion_Id])
,('DimCarrier_Id',src.[DimCarrier_Id])
,('DimOperator_Id',src.[DimOperator_Id])
) ca (id_type, id_value)
inner join (
select
fact.id fact_id, ca.id_type, ca.id_value
from AppsFlyer.FactDeviceBuild AS fact
cross apply (
values
('DimDevice_Id',fact.[DimDevice_Id])
,('DimDeviceModel_Id',fact.[DimDeviceModel_Id])
,('DimPlatform_Id',fact.[DimPlatform_Id])
,('DimOSVersion_Id',fact.[DimOSVersion_Id])
,('DimSDKVersion_Id',fact.[DimSDKVersion_Id])
,('DimCarrier_Id',fact.[DimCarrier_Id])
,('DimOperator_Id',fact.[DimOperator_Id])
) ca (id_type, id_value)
where ca.id_value IS NOT NULL
) as f on ca.id_type = f.id_type and ca.id_value = f.id_value
Note I have not used the "unpivot" feature of TSQL as I prefer the syntax you see above. There is NO additional performance disadvantage when using this apply/values syntax.
NB: all 7 of those id type columns must be "compatible" data types for the "unpivot" to work without error. All 7 as integer for example, which would make the id_value a column of integers.

SQL Server - using Over/Partition By in complex query

We have many complex queries which involve a lot of columns and joins (see the example below) that are implemented as views.
In some cases these queries return duplicate rows which then have to be programmatically removed by the consuming app. Therefore, we would like to enhance the SQL query to eliminate the duplicates, and speed up the retrieval process.
I know that I can use OVER / PARTITION BY logic to do this, but I am not sure of how to modify the queries to obtain a working syntax.
Here is an example:
SELECT
Main.MfgOrder.OrderNumber,
Main.MfgOrder.DesignBOMID,
Main.Design_Plant.PlantID,
Main.MfgOrder_Operation.OrderOpID,
Main.MfgOrder_Operation.DesignOpID,
Main.MfgOrder_Operation.OpSeq,
Main.MfgOrder_Operation.Description,
Main.MfgOrder_Operation.CompletionStatus,
Main.MfgOrder__Shift.OrderShiftID,
Main.MfgOrder__Shift.WorkCenterMachineID,
Main.MfgOrder___Event.OrderEventID,
Main.MfgOrder____Reel.OrderReelID,
Main.MfgOrder____Reel.ReelNumber,
Main.MfgOrder____Reel.Location,
Main.MfgOrder____Reel.Test_Status AS Test_Status_Reel,
Main.MfgOrder____Reel.Test_Disposition AS Test_Disposition_Reel,
Main.MfgOrder____Reel.LabReleased,
Main.MfgOrder____Reel.ShipReelsBypassSet,
Main.MfgOrder_____Length.OrderLengthID,
Main.MfgOrder_____Length.LengthType,
Main.MfgOrder_____Length.LocationOnReel,
Main.MfgOrder_____Length.LocationOnLength,
Main.MfgOrder_____Length.TrialNumber,
Main.MfgOrder_____Length.SampleNumber,
Main.MfgOrder_____Length.PrintNumber,
Main.MfgOrder_____Length.Test_Status AS Test_Status_Length,
Main.MfgOrder_____Length.Test_Category,
Main.MfgOrder_____Length.Test_Disposition AS Test_Disposition_Length,
Main.MfgOrder_____Length.SampleSubmittedBy,
Main.MfgOrder_____Length.SampleSubmittedDate,
Main.MfgOrder_____Length.BypassTesting,
Main.MfgOrder_____Length_OperatorQty.Sample1Destination,
Main.MfgOrder_____Length_OperatorQty.Sample2Destination,
Main.MfgOrder_____Length_OperatorQty.Sample3Destination,
Main.MfgOrder______Component.OrderComponentID,
Main.MfgOrder______Component.DesignComponentID,
Main.MfgOrder______Component.ItemNo,
Main.MfgOrder_______Test.LabTestID,
Main.MfgOrder_______Test.OrderTestID,
Main.MfgOrder_______Test.TestComplete,
Main.MfgOrder_______Test.TestStatus,
Main.MfgOrder________Marker2.OrderMarkerID,
Master.Color.ColorName,
Master.LabTest.ExcludeFromPassFail,
CASE
WHEN Main.Design_Component.Component_Label IS NULL
THEN 'Unknown'
ELSE Main.Design_Component.Component_Label
END AS Component_Label
FROM
Main.MfgOrder
INNER JOIN
Main.Design__BOM ON Main.MfgOrder.DesignBOMID = Main.Design__BOM.DesignBOMID
INNER JOIN
Main.Design_Plant ON Main.Design__BOM.DesignPlantID = Main.Design_Plant.DesignPlantID
INNER JOIN
Main.MfgOrder_Operation ON Main.MfgOrder.OrderNumber = Main.MfgOrder_Operation.OrderNumber
INNER JOIN
Main.MfgOrder__Shift ON Main.MfgOrder_Operation.OrderOpID = Main.MfgOrder__Shift.OrderOpID
INNER JOIN
Main.MfgOrder___Event ON Main.MfgOrder__Shift.OrderShiftID = Main.MfgOrder___Event.OrderShiftID
INNER JOIN
Main.MfgOrder____Reel ON Main.MfgOrder___Event.OrderEventID = Main.MfgOrder____Reel.OrderEventID
INNER JOIN
Main.MfgOrder_____Length ON Main.MfgOrder____Reel.OrderReelID = Main.MfgOrder_____Length.OrderReelID
LEFT OUTER JOIN
Main.MfgOrder______Component ON Main.MfgOrder_____Length.OrderLengthID = Main.MfgOrder______Component.OrderLengthID
LEFT OUTER JOIN
Main.MfgOrder_______Test ON Main.MfgOrder______Component.OrderComponentID = Main.MfgOrder_______Test.OrderComponentID
LEFT OUTER JOIN
Main.MfgOrder________Marker2 ON Main.MfgOrder_______Test.OrderTestID = Main.MfgOrder________Marker2.OrderTestID
LEFT OUTER JOIN
Main.Design_Component ON Main.MfgOrder______Component.DesignComponentID = Main.Design_Component.DesignComponentID
LEFT OUTER JOIN
Master.Color ON Main.MfgOrder______Component.TapeColorID = Master.Color.ColorNumber
LEFT OUTER JOIN
Master.LabTest ON Main.MfgOrder_______Test.LabTestID = Master.LabTest.LabTestID
LEFT OUTER JOIN
Main.MfgOrder_____Length_OperatorQty ON Main.MfgOrder______Component.OrderLengthID = Main.MfgOrder_____Length_OperatorQty.OrderLengthID
you can use row_number as below: Below query will not select duplicate only on OrderNumber, if you need to add other columns you add accordingly
Select * from (
Select
RowN = Row_Number() over( partition by Main.MfgOrder.OrderNumber order by Main.MfgOrder.OrderNumber),
--- All your select columns and all your query with joins
) a
Where a.RowN = 1
Is the entire row duplicated exactly? If so then just add DISTINCT
SELECT DISTINCT
...
FROM
...
If you are getting duplicate rows where most columns the same but some columns are different then GROUP BY the columns that are the same and select MIN(column_name) for the ones that are causing the extra rows to appear.

Having issues with INNER JOIN in SQL Server

I'm trying to select rows from 2 tables with only one SQL statement. Could anybody help me figure out how to make this code work?
This is my SQL statement:
SELECT *.
FROM PersonalTable
INNER JOIN ON Employees.PersonalID = PersonalTable.PersonalID
WHERE PersonalID = " + PersonalID.ToString()
You have to list the Employees table as the target of your join:
SELECT * FROM PersonalTable
INNER JOIN Employees
ON Employees.PersonalID = PersonalTable.PersonalID
WHERE Employees.PersonalID= etc

Compare a "temp' table with values in CTE, then update two different tables

I have a "temp' table populated from an enrollment transportable in java. What I am doing is comparing the "temp" table with values I am populating in a CTE with a select query. What I need to do next is update two different tables. Here is my query for the comparison of the "temp" table and CTE:
WITH CTE AS
(
SELECT S.SYS_USER_NAME, PG.PAX_ID
FROM component.SYS_USER S
INNER JOIN component.PAX_GROUP PG
ON S.PAX_ID = PG.PAX_ID
WHERE (ROLE_CODE = 'AC' and THRU_DATE is null) or
(ROLE_CODE = 'DLRP' and THRU_DATE is null)
)
SELECT * FROM CTE
INNER JOIN component.TEMP_CONTROL_NUM
ON TEMP_CONTROL_NUM.CONTROL_NUM = CTE.SYS_USER_NAME
What I want to do next is update two different tables. One I need to set a status column as inactive and the other I need to set a thru date.
The issue I am having is writing an UPDATE with a SELECT. I have something like:
UPDATE component.SYS_USER SET STATUS = 'I'
WHERE SYS_USER_NAME =
(SELECT * FROM CTE INNER JOIN component.TEMP_CONTROL_NUM ON
TEMP_CONTROL_NUM = CTE.SYS_USER_NAME)
Would this be correct? I realize I am only attempting to update one table but I figure if I have one table updating, I can figure out the other. It doesn't seem to be.
Thank you in advance.
;WITH CTE as
(
...
)
UPDATE u SET
STATUS = 'I'
FROM component.SYS_USER u
INNER JOIN CTE c on c.SYS_USER_NAME = u.SYS_USER_NAME
INNER JOIN component.TEMP_CONTROL_NUM t ON t.TEMP_CONTROL_NUM = c.SYS_USER_NAME

How to join one select with another when the first one not always returns a value for specific row?

I have a complex query to retrieve some results:
EDITED QUERY (added the UNION ALL):
SELECT t.*
FROM (
SELECT
dbo.Intervencao.INT_Processo, analista,
ETS.ETS_Sigla, ATC.ATC_Sigla, PAT.PAT_Sigla, dbo.Assunto.SNT_Peso,
CASE
WHEN ETS.ETS_Sigla = 'PE' AND (PAT.PAT_Sigla = 'LIB' OR PAT.PAT_Sigla = 'LBR') THEN (0.3*SNT_Peso)
WHEN ETS.ETS_Sigla = 'CD' THEN (0.3*SNT_Peso)*0.3
ELSE SNT_Peso
END AS PESOAREA,
CASE
WHEN a.max_TEA_FimTarefa IS NULL THEN a.max_TEA_InicioTarefa
ELSE a.max_TEA_FimTarefa
END AS DATA_INICIO_TERMINO,
ROW_NUMBER() OVER (PARTITION BY ATC.ATC_Sigla, a.SRV_Id ORDER BY TEA_FimTarefa DESC) AS seqnum
FROM dbo.Tarefa AS t
INNER JOIN (
SELECT
MAX(dbo.TarefaEtapaAreaTecnica.TEA_InicioTarefa) AS max_TEA_InicioTarefa,
MAX (dbo.TarefaEtapaAreaTecnica.TEA_FimTarefa) AS max_TEA_FimTarefa,
dbo.Pessoa.PFJ_Descri AS analista, dbo.AreaTecnica.ATC_Id, dbo.Tarefa.SRV_Id
FROM dbo.TarefaEtapaAreaTecnica
LEFT JOIN dbo.Tarefa ON dbo.TarefaEtapaAreaTecnica.TRF_Id = dbo.Tarefa.TRF_Id
LEFT JOIN dbo.AreaTecnica ON dbo.TarefaEtapaAreaTecnica.ATC_Id = dbo.AreaTecnica.ATC_Id
LEFT JOIN dbo.ServicoAreaTecnica ON dbo.TarefaEtapaAreaTecnica.ATC_Id = dbo.ServicoAreaTecnica.ATC_Id
AND dbo.Tarefa.SRV_Id = dbo.ServicoAreaTecnica.SRV_Id
INNER JOIN dbo.Pessoa ON dbo.Pessoa.PFJ_Id = dbo.ServicoAreaTecnica.PFJ_Id_Analista
GROUP BY dbo.AreaTecnica.ATC_Id, dbo.Tarefa.SRV_Id, dbo.Pessoa.PFJ_Descri
) AS a ON t.SRV_Id = a.SRV_Id
INNER JOIN dbo.TarefaEtapaAreaTecnica AS TarefaEtapaAreaTecnica_1 ON
t.TRF_Id = TarefaEtapaAreaTecnica_1.TRF_Id
AND a.ATC_Id = TarefaEtapaAreaTecnica_1.ATC_Id
AND a.max_TEA_InicioTarefa = TarefaEtapaAreaTecnica_1.TEA_InicioTarefa
LEFT JOIN AreaTecnica ATC ON TarefaEtapaAreaTecnica_1.ATC_Id = ATC.ATC_Id
LEFT JOIN Etapa ETS ON TarefaEtapaAreaTecnica_1.ETS_Id = ETS.ETS_Id
LEFT JOIN ParecerTipo PAT ON TarefaEtapaAreaTecnica_1.PAT_Id = PAT.PAT_Id
LEFT OUTER JOIN dbo.Servico ON a.SRV_Id = dbo.Servico.SRV_Id
INNER JOIN dbo.Intervencao ON dbo.Servico.INT_Id = dbo.Intervencao.INT_Id
LEFT JOIN dbo.Assunto ON dbo.Servico.SNT_Id = dbo.Assunto.SNT_Id
) t
The result is following:
It works good, the problem is that I was asked that if when a row is not present on this query, it must contain values from another table (ServicoAreaTecnica), so I got this query for the other table based on crucial information of the first query. So if I UNION ALL I get this:
Query1 +
UNION ALL
SELECT INN.INT_Processo,
PES.PFJ_Descri,
NULL, --ETS.ETS_Sigla,
ART.ATC_Sigla,
NULL ,--PAT.PAT_Sigla,
ASS.SNT_Peso,
NULL, --PESOAREA
NULL, --DATA_INICIO_TERMINO
NULL --seqnum
FROM dbo.ServicoAreaTecnica AS SAT
INNER JOIN dbo.AreaTecnica AS ART ON ART.ATC_Id = SAT.ATC_Id
INNER JOIN dbo.Servico AS SER ON SER.SRV_Id = SAT.SRV_Id
INNER JOIN dbo.Assunto AS ASS ON ASS.SNT_Id = SER.SNT_Id
INNER JOIN dbo.Intervencao AS INN ON INN.INT_Id = SER.INT_Id
INNER JOIN dbo.Pessoa AS PES ON PES.PFJ_Id = SAT.PFJ_Id_Analista
The result is following:
So what I want to do is to remove row number 1 because row number 2 exists on the first query, I think I got it explained better this time. The result should be only row number 1, row number 2 would appear only if query 1 doesn't retrieve a row for that particular INN.INT_Processo.
Thanks!
Ok, there are two ways to reduce your record set. Given that you've already written the code to produce the table with the extra rows, it might be easiest to just add code to reduce that:
Select * from
(Select *
, Row_Number() over
(partition by IntProcesso, Analista order by ISNULL(seqnum, 0) desc) as RN
from MyResults) a
where RN = 1
This will assign row_number 1 to any rows that came from your first query, or to any rows from the second query that do not have matches in the first query, then filter out extra rows.
You could also use outer joins with isnull or coalesce, as others have suggested. Something like this:
Select ISNULL(a.IntProcesso, b.IntProcesso) as IntProcesso
, ISNULL(a.Analista, b.Analista) as Analista
, ISNULL(a.ETSsigla, b.ETSsigla) as ETSsigla
[repeat for the rest of your columns]
from Table1 a
full outer join Table2 b
on a.IntProcesso = b.IntProcesso and a.Analista = b.Analista
Your code is hard to read, because of the lengthy names of everything (and to be honest, the fact that they're in a language I don't speak also makes it a lot harder).
But how about: replacing your INNER JOINs with LEFT JOINs, adding more LEFT JOINs to draw in the alternative tables, and introducing ISNULL clauses for each variable you want in the results?
If you do something like ... Query1 Right Join Query2 On ... that should get only the rows in Query2 that don't appear in Query 1.

Resources