Inconsistent Results from Cross-Server Query - sql-server

I have a query that yields inconsistent results. I receive a different number of rows almost every time I run the query. I receive no errors. I have tried running the query from all of the servers in the query. I also tried running the query from a fourth unrelated server that is linked to both servers in the query. I tried running each of the CTEs on its own and always get consistent results. Only the last part of the query yields inconsistent results.
Does anyone know what could be causing these inconsistent results? Thanks!
with customerOrderMatches as (
select
SAPOX.docentry
,SAPO.cardcode as 'O CC'
,SAPCMS.CardCode+'-'+SAPCMS.Address as 'OrigShipToID'
,SAPCMB.CardCode+'-'+SAPCMB.Address as 'OrigCustID'
from [Server1].[BowDB].[dbo].ORDR SAPO
join [Server1].[BowDB].[dbo].RDR12 SAPOX
on SAPO.docentry=SAPOX.docentry
left outer join [Server1].[BowDB].[dbo].CRD1 SAPCMS --ship to match
on SAPCMS.cardcode=SAPO.cardcode
and SAPCMS.Address=SAPO.Shiptocode
and SAPCMS.AdresType='S'
and SAPCMS.Street=SAPOX.StreetS
left outer join [Server1].[BowDB].[dbo].CRD1 SAPCMB --bill to match
on SAPCMB.cardcode=SAPO.cardcode
and SAPCMB.Address=SAPO.PayToCode
and SAPCMB.AdresType='B'
and SAPCMB.Street=SAPOX.StreetB
where
SAPO.cardcode NOT IN (
'1001', '1002', '1003'
)
AND SAPO.canceled = 'N'
),
customerRank as (
SELECT
rtrim(C.custid) AS 'custid'
,COUNT(SLShipper.ShipperID) as 'totalShippers'
,Row_number() OVER (ORDER BY COUNT(SLShipper.ShipperID) DESC) AS 'customerRank'
FROM [MLSQL12].[SLapplication15].dbo.customer C
left outer join [MLSQL12].[SLapplication15].dbo.SOShipHeader SLShipper
on SLShipper.custid=C.custid
GROUP BY C.CustID
),
customerShipToRank as (
SELECT
rtrim(SOA.CustID) AS 'custid'
,rtrim(SOA.ShiptoID) as 'shiptoid'
,COUNT(SLShipper.ShipperID) as 'totalShippers'
,cast(Row_number() OVER(Partition by SOA.custid ORDER BY COUNT(SLShipper.ShipperID) DESC) as int) AS 'ShipToRank'
,customerRank
FROM [MLSQL12].[SLapplication15].dbo.soaddress SOA
left outer join [MLSQL12].[SLapplication15].dbo.SOShipHeader SLShipper
on SLShipper.CustID=SOA.CustId
and SLShipper.ShiptoID=SOA.shiptoid
join customerRank CR
on CR.custid=SOA.CustID
GROUP BY
SOA.CustID
,SOA.ShiptoID
,customerRank
),
combinedData as (
select
COM.Docentry
,CXR.*
,CSTR.*
from customerOrderMatches COM
join MLSQL15.HistoricalData.Hist.CustomerXRef CXR
on CXR.OrigShipToID=COM.OrigShipToID collate SQL_Latin1_General_CP850_CI_AS
and CXR.OrigCustID=COM.OrigCustID collate SQL_Latin1_General_CP850_CI_AS
left outer join customerShipToRank CSTR
on CSTR.shiptoid =CXR.BKShiptoId
and CSTR.custid =CXR.BKCustId
)
select
*
from combinedData CD
where CONCAT(customerRank,ShipToRank) in (
select MIN(CONCAT(customerRank,ShipToRank))
from combinedData
group by docentry)
order by docentry
Other random facts about the situation:
-I realize that there are probably inefficiencies in my query that could be optimized. However, this should not result in inconsistent results.
-One database is an SAP DB.
-One DB is a Microsoft Dynamics SL DB.
-One DB is our own DB we created for acquisition data.
Update (12/12/2022)
One of the columns returned is a basic primary key of an order in an order table. I ran the query six times and got the following results:
Query Run Number
Total Rows
Lowest DocEntry
Highest DocEntry
1
14509
9
31412
2
14509
9
31412
3
5455
105
31408
4
5448
108
31411
5
14509
9
31412
6
5181
105
31411

Related

Query runs slower when SELECT clause is used

I have a query in SQL Server with 6 JOINs and 1 LEFT JOIN to tables and views. It returns 16k records in about 1 second if the select clause is "SELECT *"
As soon as I specify even one column to display (SELECT ItemID, for example) the query slows down to about 70 seconds.
Query #1 (2s) - SELECT *:
SELECT *
FROM (SELECT LinkedToSet, LinkedToCopy, ',' + STRING_AGG(LocationID,',') + ',' Locs, count(1) OVER (PARTITION BY LinkedToSet) Copies
FROM Inventory.Locations WHERE LinkedToSet is not null AND (State & 4096)>0 GROUP BY LinkedToSet, LinkedToCopy) l
JOIN Bricklink_Set_Query bsq on l.LinkedToSet=bsq.Number
JOIN Bricklink.Set_Parts_Query bsp on l.LinkedToSet=bsp.SetNum AND bsp.Extra=0
JOIN Bricklink.Item_List i on bsp.ItemType=i.ItemType AND bsp.ItemID=i.Number
JOIN Bricklink.Category_List cat on i.Category_ID=cat.CatID
JOIN Bricklink.Color_List col on bsp.ColorID=col.ColorID
LEFT JOIN (SELECT LocationID, ItemType, ItemNum, ColorID, sum(QtyFound) as InvPcs
FROM Inventory.Item_History
GROUP BY LocationID, ItemType, ItemNum, ColorID) as h ON l.Locs like concat('%,',h.locationID,',%') AND h.ItemType=bsp.ItemType AND h.ItemNum=bsp.ItemID AND h.ColorID=bsp.ColorID
Actual Execution Plan: https://www.brentozar.com/pastetheplan/?id=SJD7Qemf_
Query #2 (81s) - SELECT a single column
SELECT bsp.ItemID
FROM (SELECT LinkedToSet, LinkedToCopy, ',' + STRING_AGG(LocationID,',') + ',' Locs, count(1) OVER (PARTITION BY LinkedToSet) Copies
FROM Inventory.Locations WHERE LinkedToSet is not null AND (State & 4096)>0 GROUP BY LinkedToSet, LinkedToCopy) l
JOIN Bricklink_Set_Query bsq on l.LinkedToSet=bsq.Number
JOIN Bricklink.Set_Parts_Query bsp on l.LinkedToSet=bsp.SetNum AND bsp.Extra=0
JOIN Bricklink.Item_List i on bsp.ItemType=i.ItemType AND bsp.ItemID=i.Number
JOIN Bricklink.Category_List cat on i.Category_ID=cat.CatID
JOIN Bricklink.Color_List col on bsp.ColorID=col.ColorID
LEFT JOIN (SELECT LocationID, ItemType, ItemNum, ColorID, sum(QtyFound) as InvPcs
FROM Inventory.Item_History
GROUP BY LocationID, ItemType, ItemNum, ColorID) as h ON l.Locs like concat('%,',h.locationID,',%') AND h.ItemType=bsp.ItemType AND h.ItemNum=bsp.ItemID AND h.ColorID=bsp.ColorID
Actual execution plan: https://www.brentozar.com/pastetheplan/?id=BJTr4x7Gu
The execution plans look totally different from each other and I'm not sure why. I've also tried wrapping the SELECT * and querying that, but some of these tables/views have the exact same field names, especially on the joins, so SQL Server throws an error:
This column 'foo' was specified multiple times.
How do I achieve the performance of SELECT * but limit which columns I display?
P.S. 2 Notes - 1) My desired select statement is obviously more complex than this and 2) Even using the full select statement, if I add a WHERE clause and restrict the query there, it runs in <1 second. If that plan would be useful I can post it as well.

Combine multiple left joins in 1 query

I have two queries that I would like to combine. One query is left joining columns in the same table, the other query is left joining columns from two different tables. Both queries have the same table, just unsure how to properly set up the query.
1st Query:
SELECT BIZ_GROUP,
ORDER_ID,
STATION,
A.TC_DATE,
WANT_DATE,
TIME_SLOT,
JOB_CODE,
[ADDRESS],
CITY,
A.TECH_ID,
A.PREMISE,
ISNULL(B.LAST_ARRIVED, A.LAST_ARRIVE) AS ARRIVED,
ORDER_CLOSED,
COMP_STATUS,
WORK_STATUS,
REMARKS,
CORRECTION
FROM MET_timecommit A
LEFT JOIN(SELECT premise,
TC_DATE,
TECH_ID,
MIN(last_arrive) AS LAST_ARRIVED
FROM MET_timecommit
WHERE PREMISE IS NOT NULL
GROUP BY premise,
TC_DATE,
TECH_ID) B ON B.TC_DATE = A.TC_DATE
AND B.PREMISE = A.PREMISE
2nd query:
SELECT *
FROM MET_timecommit
LEFT JOIN (SELECT ORDER_ID,
created,
host_creation,
went_to
FROM workload
WHERE went_to >= getdate()-365) C ON C.went_to=MET_timecommit.TC_DATE
AND C.order_id=MET_timecommit.order_id
Evidently I am not used to this forum. You all don't have to be so rude. TDP was able to help me out based on what I provided. All other comments were unnecessary.
This should bring back the rows for both tables B and C for each row of table A:
SELECT A.BIZ_GROUP,
A.ORDER_ID,
A.STATION,
A.TC_DATE,
A.WANT_DATE,
A.TIME_SLOT,
A.JOB_CODE,
A.[ADDRESS],
A.CITY,
A.TECH_ID,
A.PREMISE,
ISNULL(B.LAST_ARRIVED, A.LAST_ARRIVE) AS ARRIVED,
A.ORDER_CLOSED,
A.COMP_STATUS,
A.WORK_STATUS,
A.REMARKS,
A.CORRECTION,
C.*
FROM MET_timecommit A
LEFT JOIN(SELECT premise,
TC_DATE,
TECH_ID,
MIN(last_arrive) AS LAST_ARRIVED
FROM MET_timecommit
WHERE PREMISE IS NOT NULL
GROUP BY premise,
TC_DATE,
TECH_ID) B ON B.TC_DATE = A.TC_DATE
AND B.PREMISE = A.PREMISE
LEFT JOIN (SELECT ORDER_ID,
created,
host_creation,
went_to
FROM workload
WHERE went_to >= getdate()-365) C ON C.went_to=A.MET_timecommit.TC_DATE
AND C.order_id=A.MET_timecommit.order_id

Sum of All Total related to a Vulnerability Name

I have written a query
SELECT Year(outertblissues.opendt) AS Years,
Month(outertblissues.opendt) AS Months,
outertblvulnerability.vulname,
Count(outertblvulnerability.vulid) Vulcount
FROM tbl_apptestdetails AS outertblapptestdetails
INNER JOIN tbl_applicationlist AS outertblapplicationlist
ON outertblapptestdetails.appid = outertblapplicationlist.appid
INNER JOIN tbl_bu AS outertblbu
ON outertblbu.buid = outertblapplicationlist.buid
INNER JOIN tbl_issues AS outertblissues
ON outertblapptestdetails.testdetailid =
outertblissues.testdetailid
AND outertblissues.status NOT IN( '1', '4' )
INNER JOIN tbl_vulnerability AS outertblvulnerability
ON outertblissues.vulid = outertblvulnerability.vulid
GROUP BY Year(outertblissues.opendt),
Month(outertblissues.opendt),
outertblvulnerability.vulname
ORDER BY vulcount DESC
Which gives the following result
Now a want one more column Name as SumOfCount which gives the Sum of all VulCount Related to a particular VulName For example in front of "Additional Issues" The SumOfCount Should be 8 , Similarly for others
If you use Sql Server 2012 or higher you can try instruction Sum() over partition by
SUM(VulCount) OVER(PARTITION BY VulName)

How to display only the MAX results from a query

I am new to writing MS SQL queries and I am trying to display only the record with the highest field named RecordVersion.
Below is the query that works but displays all records:
SELECT
PriceCalendars.PriceProgramID,
PriceCalendars.EffectiveDateTime,
PriceSchedules.Price,
PriceSchedules.PLU,
items.Descr,
PriceSchedules.LastUpdate,
PriceSchedules.LastUpdatedBy,
PriceSchedules.RecordVersion,
PriceSchedules.PriceScheduleUniqueID
FROM
PriceCalendars
INNER JOIN PriceSchedules ON PriceCalendars.PriceProgramID = PriceSchedules.PriceProgramID
INNER JOIN items ON PriceSchedules.PLU = items.PLU
WHERE
(PriceSchedules.PLU = 'SLS10100103')
AND (PriceCalendars.EffectiveDateTime = '2016-03-22')
Here are the query results:
PriceProgramID EffectiveDateTime Price PLU Descr LastUpdate LastUpdatedBy RecordVersion PriceScheduleUniqueID
1 2016-03-22 00:00:00.000 35.00 SLS10100103 Architecture Adult from NP POS 2015-01-22 07:53:15.000 GX70,83 9 569
1 2016-03-22 00:00:00.000 32.00 SLS10100103 Architecture Adult from NP POS 2014-02-25 16:22:46.000 GX70,83 5 86180
The first line of the results has RecordVersion being 9 and the second line results is 5, I only want the higher record displaying, the one that returned RecordVersion = 9.
Every time I try to use the MAX command I get errors or the group by and I have tried every example I could find on the web but nothing seems to work.
Using MS SQL 2012.
Thanks,
Ken
Try the following query which attempts to solve your problem by ordering the returned rows by RecordVersion DESC and then SELECTs just the first row.
SELECT TOP 1
PriceCalendars.PriceProgramID,
PriceCalendars.EffectiveDateTime,
PriceSchedules.Price,
PriceSchedules.PLU,
items.Descr,
PriceSchedules.LastUpdate,
PriceSchedules.LastUpdatedBy,
PriceSchedules.RecordVersion,
PriceSchedules.PriceScheduleUniqueID
FROM
PriceCalendars
INNER JOIN PriceSchedules ON PriceCalendars.PriceProgramID = PriceSchedules.PriceProgramID
INNER JOIN items ON PriceSchedules.PLU = items.PLU
WHERE
(PriceSchedules.PLU = 'SLS10100103')
AND (PriceCalendars.EffectiveDateTime = '2016-03-22')
ORDER BY
RecordVersion DESC
All group by columns should be in select ,that's the rule of group by.How group by works is for every distinct combination of group by columns,arrange remaining columns into groups,so that any aggregation can be applied,in your case I am not sure what group by columns are unique with out test date.here is one version which use row number which gives you the output desired
Remember ,order by last updated date is the one which decides rows order and assign numbers
WITH CTE
AS
(
SELECT PriceCalendars.PriceProgramID,
PriceCalendars.EffectiveDateTime,
PriceSchedules.Price,
PriceSchedules.PLU,
items.Descr,
PriceSchedules.LastUpdate,
PriceSchedules.LastUpdatedBy,
PriceSchedules.RecordVersion,
PriceSchedules.PriceScheduleUniqueID,
ROW_NUMBER() OVER (PARTITION BY PriceSchedules.RecordVersion ORDER BY PriceSchedules.LastUpdatedBy) AS RN
FROM
PriceCalendars
INNER JOIN PriceSchedules ON PriceCalendars.PriceProgramID = PriceSchedules.PriceProgramID
INNER JOIN items ON PriceSchedules.PLU = items.PLU
WHERE
(PriceSchedules.PLU = 'SLS10100103')
AND (PriceCalendars.EffectiveDateTime = '2016-03-22')
)
SELECT * FROM CTE WHERE RN=1

T-SQL UNION Performance issue

I have two kinds of query with did the same job here
Query 1 :
SELECT MP.MemberName FROM MemberProfile MP
LEFT JOIN Order O ON MP.MemberID = O.MemberID
WHERE O.TotalAmount >= 100
UNION
SELECT MP.MemberName FROM MemberProfile MP
LEFT JOIN Order O ON MP.MemberID = O.MemberID
WHERE O.Quantity >= 10
Query 2 :
;WITH cte AS (
SELECT MP.MemberName, O.Quantity, O.TotalAmount FROM MemberProfile MP
LEFT JOIN Order O ON MP.MemberID = O.MemberID
)
SELECT MemberName FROM cte WHERE TotalAmount >= 100
UNION
SELECT MemberName FROM cte WHERE Quantity >= 10
In real environment will be more complicated query, these just a simple version for other to read
Question:
Is it better to use CTE instead of using JOIN every single time, base on performance and also redundancy?
Is there a better way to do this UNION or even UNION ALL query other than these way.
I don't think that there will any big difference between CTE and JOIN in your case. SQL Server optimization will convert it to something complete different and these two queries will produce probably the same result. You can try to add indexes on TotalAmount and Quantity if selectivity is high.

Resources