Temp Table with WHERE Concat LIKE - sql-server

I have a table I want to keep open to sort multiple ways on the fly, so I am inserting into a temp table, but when I try to CONCAT the WHERE statement it can take up to 5 minutes for less then 5k rows ... how would I do a CONCAT to find a string in a CONCAT string and not take forever... if i do a basic select i can return stuff within a few seconds
IF OBJECT_ID('tempdb..#TempTest') IS NOT NULL
DROP TABLE #TempTest
SELECT TOP 1000 *
INTO #TempTest
FROM
(SELECT
hcp_urls_id,
CONCAT (hcp_protocol_text, hcp_protocol_split, hcp_domains_text, hcp_paths_text, '?', hcp_querystrings_text) AS hcp_urls_concat,
hcp_urls_page_statuscode
FROM
hcp_urls
INNER JOIN
hcp_paths ON hcp_paths_id = hcp_urls_paths_id
INNER JOIN
hcp_domains ON hcp_domains_id = hcp_urls_domains_id
INNER JOIN
hcp_protocol ON hcp_protocol_id = hcp_urls_protocol_id
FULL OUTER JOIN
hcp_querystrings ON hcp_querystrings_id = hcp_urls_querystrings_id
WHERE
CONCAT (hhcp_protocol_text, hcp_protocol_split, hcp_domains_text,hcp_paths_text, '?', hcp_querystrings_text) LIKE '%www.test.com/url%') AS tmpTest

Related

Multiple INNER JOIN SELECT query not returning data

This is a stored procedure to select the full details of a wine.
It takes as a parameter a storage location ID.
This builds properly and is similar in structure to many sp's I have written that work,
however it returns no data. Is there something I am missing?
CREATE PROCEDURE [sp_retrieveInventory_Full]
(
#StorageLocationID [int]
)
AS
BEGIN
SELECT [WineName],
[RackID],
[RackColumn],
[RackRow],
[WineTypeID],
[WineVarietyID],
[VintnerName],
[dbo].[Vintner].[Country],
[dbo].[Vintner].[StateProvince],
[dbo].[Vintner].[Region],
[VendorName],
[Vintage],
[PurchaseDate],
[PurchasePrice],
[BottleSizeID],
[ABV],
[DrinkByDate],
[FoodType],
[TastingNotes],
[RatedBy],
[RatingScore]
FROM [dbo].[StorageLocation]
INNER JOIN [dbo].[Wine]
ON [dbo].[StorageLocation].[WineID] = [dbo].[Wine].[WineID]
INNER JOIN [dbo].[Vintner]
ON [dbo].[Vintner].[VintnerID] = [dbo].[Wine].[VintnerID]
INNER JOIN [dbo].[Vendor]
ON [dbo].[Vendor].[VendorID] = [dbo].[Wine].[VendorID]
INNER JOIN [dbo].[Pairing]
ON [dbo].[Pairing].[PairingID] = [dbo].[Wine].[PairingID]
INNER JOIN [dbo].[Rating]
ON [dbo].[Rating].[RatingID] = [dbo].[Wine].[RatingID]
WHERE [dbo].[StorageLocation].[StorageLocationID] = #storageLocationID
END
GO
When a query reruns no result it's because no records exists that satisfy the conditions in it's where clause, or, in case of queries that contains inner joins, at least one of the joins on condition returns no records.
The easiest way to figure out what join is messing up your query is to start removing the joins one by one, but to do that, you have to first change the select clause.
What I like to do is this: Start with all the joins except the last one - see if it returns any records:
SELECT 1
FROM [dbo].[StorageLocation]
INNER JOIN [dbo].[Wine]
ON [dbo].[StorageLocation].[WineID] = [dbo].[Wine].[WineID]
INNER JOIN [dbo].[Vintner]
ON [dbo].[Vintner].[VintnerID] = [dbo].[Wine].[VintnerID]
INNER JOIN [dbo].[Vendor]
ON [dbo].[Vendor].[VendorID] = [dbo].[Wine].[VendorID]
INNER JOIN [dbo].[Pairing]
ON [dbo].[Pairing].[PairingID] = [dbo].[Wine].[PairingID]
-- INNER JOIN [dbo].[Rating]
-- ON [dbo].[Rating].[RatingID] = [dbo].[Wine].[RatingID]
WHERE [dbo].[StorageLocation].[StorageLocationID] = #storageLocationID
If not, comment out the next join and run the query again. Rinse and repeat.
Please note, however, that there might be more than one inner join that prevents the query from returning records.

SQL Query to get data from various databases

I wrote the below query to pull the data from different databases. I have created two temp tables to pull the data from two different databases and finally a select statement from the original database to join all the tables. My query is getting executed but not getting any data.(Report is blank). I tried executing the two temp tables separately. it is giving the correct data. But when I execute the whole query, the result is blank. Below is the query. Please help.
"set fmtonly off
use GODSDB
IF object_id('tempdb..#CISIS_Call_Log') IS NOT NULL DROP TABLE #CISIS_Call_Log
select *
into #CISIS_Call_Log
from OPENQUERY (CSISDB,
'select
ccl.ContractOID,
ccl.db_insertdate,
ccl.ContractCallLogStatusIdentifier,
ccl.db_UpdateDate,
ccp.ContractCallLogPurposeOID,
ccp.ContractCallLogPurposeIdentifier,
ccp.Description
from csisdb.dbo.ContractCallLog CCL
inner join csisdb.dbo.ContractCallLogPurpose CCP on ccl.ContractCallLogPurposeIdentifier = ccp.ContractCallLogPurposeIdentifier
where JurisdictionShortIdentifier = ''ON''
AND ContractCallLogStatusIdentifier IN (''DNR'', ''NR'')
')
IF object_id('tempdb..#CMS_Campaign') IS NOT NULL DROP TABLE #CMS_Campaign
select *
into #CMS_Campaign
from OPENQUERY (BA_GBASSTOCMS, '
Select
SystemSourceIdentifier,
ContractOID,
OfferSentDate,
CampaignOfferTypeIdentifier,
CampaignContractStatusIdentifier,
CampaignContractStatusUpdateDate,
DeclineDate,
CampaignOfferOID,
CampaignOID,
CampaignStartDate,
CampaignEndDate,
Jurisdiction,
CampaignDescription
from CMS.dbo.vw_CampaignInfo
where Jurisdiction = ''ON''
and CampaignOfferTypeIdentifier = ''REN''
')
select mp.CommodityTypeIdentifier as Commodity
,c.RtlrContractIdentifier as ContractID
,cs.ContractStatusIdentifier as ContractStatus
,c.SigningDate
,cf.StartDate as FlowStartDate
,cf.EndDate as FlowEndDate
,datediff(day, getdate(), c.RenewalDate) as RemainingDays
,c.RenewalDate
,l.ContractCallLogStatusIdentifier as CallLogType
,Substring (l.Description, 1, 20) as CallPurpose
,l.db_insertDate as CallLogDate
,cms.CampaignOfferOID as OfferID
,cms.CampaignContractStatusIdentifier as OfferStatus
,cms.CampaignContractStatusUpdateDate as StatusChangeDate
,cms.DeclineDate
from Contract c
inner join contractstate cs on cs.contractoid = c.ContractOID
and cs.ContractStatusIdentifier in ('ERA', 'FLW')
and datediff(day, getdate(), c.RenewalDate) > 60
inner join SiteIdentification si on si.SiteOID = c.SiteOID
inner join MarketParticipant mp on mp.MarketParticipantOID = si.MarketParticipantOID
inner join Market m on m.MarketOID = mp.MarketOID
inner join Jurisdiction j on j.JurisdictionOID = m.JurisdictionOID
and j.CountryCode = 'CA'
and j.ProvinceOrStateCode = 'ON'
inner join ContractFlow cf on cf.ContractOID = c.ContractOID
inner join #CISIS_Call_Log l on convert(varchar(15), l.ContractOID) = c.RtlrContractIdentifier
inner join #CMS_Campaign cms on convert(varchar(15), cms.ContractOID) = c.RtlrContractIdentifier
set fmtonly on"
IF the data in each temp table is verified, then:
Try a smaller, less complex, query to test your temp tables with. Also try them using a LEFT join as well e.g.:
select
c.RtlrContractIdentifier as ContractID
, c.SigningDate
, datediff(day, getdate(), c.RenewalDate) as RemainingDays
, c.RenewalDate
, l.ContractCallLogStatusIdentifier as CallLogType
, Substring (l.Description, 1, 20) as CallPurpose
, l.db_insertDate as CallLogDate
, cms.CampaignOfferOID as OfferID
, cms.CampaignContractStatusIdentifier as OfferStatus
, cms.CampaignContractStatusUpdateDate as StatusChangeDate
, cms.DeclineDate
from Contract c
LEFT join #CISIS_Call_Log l on convert(varchar(15), l.ContractOID) = c.RtlrContractIdentifier
LEFT join #CMS_Campaign cms on convert(varchar(15), cms.ContractOID) = c.RtlrContractIdentifier
Does this return data? Does it return data from both joined tables?
If neither temp table is returning data then those join conditions need to be changed.
If both temp tables do return data from that query, then try INNER joins. If that still works, then add back more joins (one at a time) until you identify the join that causes the overall fault.
Without data for every table it just isn't possible for us to pinpoint the exact reason for a NULL result. Only you can, so you need to trouble-shoot the problem one step at a time.

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.

Get a collision free hash for a specific query or a view with SQL Server 2008

I am working on a project where I need to synchronize data from our system to an external system. What I want to achieve, is to periodically send only changed items (rows) from a custom query. This query looks like this (but with many more columns) :
SELECT T1.field1,
T1.field2,
T1.field2,
T1.field3,
CASE WHEN T1.field4 = 'some-value' THEN 1 ELSE 0 END,
T2.field1,
T3.field1,
T4.field1
FROM T1
INNER JOIN T2 ON T2.pk = T2.fk
INNER JOIN T3 ON T3.pk = T2.fk
INNER JOIN T4 ON T4.pk = T2.fk
I want to avoid to have to compare every field one to one between synchronizations. I came with the idea that I could generate a hash for every row from my query, and compare this with the hash from the previous synchronization, which will return only the changed rows. I am aware of the CHECKSUM function, but it is very collision-prone and might miss changes sometimes. However I like the way I could just make a temp table and use CHECKSUM(*), which makes maintenance easier (not having to add fields in the query and in the CHECKSUM) :
SELECT T1.field1,
T1.field2,
T1.field2,
T1.field3,
CASE WHEN T1.field4 = 'some-value' THEN 1 ELSE 0 END,
T2.field1,
T3.field1,
T4.field1
INTO #tmp
FROM T1
INNER JOIN T2 ON T2.pk = T2.fk
INNER JOIN T3 ON T3.pk = T2.fk
INNER JOIN T4 ON T4.pk = T2.fk;
-- get all columns from the query, plus a hash of the row
SELECT *, CHECKSUM(*)
FROM #tmp;
I am aware of HASHBYTES function (which supports sha1, md5, which are less prone to collisions), but it only accept varchar or varbinary, not a list of columns or * the way CHECKSUM does. Having to cast/convert every column from the query is a pain in the ... and opens the door to errors (forget to include a new field for instance)
I also noticed Change Data Capture and Change Tracking features of SQL Server, but they all seems complicated and overkill for what I am doing.
So my question : is there an other method to generate a hash from a query or a temp table that meets my criterias ?
If not, is there an other way to achieve this kind of work (to sync differences from a query)
I found a way to do exactly what I wanted, thanks to the FOR XML clause :
SELECT T1.field1,
T1.field2,
T1.field2,
T1.field3,
CASE WHEN T1.field4 = 'some-value' THEN 1 ELSE 0 END,
T2.field1,
T3.field1,
T4.field1
INTO #tmp
FROM T1
INNER JOIN T2 ON T2.pk = T2.fk
INNER JOIN T3 ON T3.pk = T2.fk
INNER JOIN T4 ON T4.pk = T2.fk;
-- get all columns from the query, plus a hash of the row (converted in an hex string)
SELECT T.*, CONVERT(VARCHAR(100), HASHBYTES('sha1', (SELECT T.* FOR XML RAW)), 2) AS sHash
FROM #tmp AS T;

Resources