T-SQL query is hanging - sql-server

First off, I didn't write this query. It's created dynamically in code I inherited. It works 99.9999% of the time so I'd prefer not to touch it. However. The following query just hangs:
SELECT
*
FROM
(
SELECT TOP 1
Track
, RequestID
, ClientName
, MatterName
, CASE
WHEN PATINDEX('% - Yellow', PhaseName) > 0 THEN REPLACE(PhaseName, ' - Yellow', '')
ELSE PhaseName
END AS PhaseName
, MPApprovalStatusName
, DateOpened
, RequestorName
, Notes
, IsNewClient
, AffiliatedClients
FROM
(
SELECT TOP 15
*
FROM
vwRequests AS T1
WHERE
ClientName LIKE '%harch%'
ORDER BY
DateOpened DESC
) AS T2
ORDER BY
DateOpened ASC
) AS T3
ORDER BY
DateOpened DESC
If I replace "harch" in the LIKE statement with "chameleon" (both should return results), results are returned with no problem. If I change the LIKE '%harch%' to = '(complete client name)', it works. If I leave LIKE, but remove the CASE statement and just output the PhaseName, it works. I experimented and did this:
SELECT TOP 15
*
, PATINDEX('% - Yellow', PhaseName)
FROM
vwRequests AS T1
WHERE
ClientName LIKE '%harch%'
ORDER BY
DateOpened DESC
It works fine. However, when I do this:
SELECT TOP 15
*
, PATINDEX('% - Yellow', PhaseName)
, REPLACE(PhaseName, ' - Yellow', '')
FROM
vwRequests AS T1
WHERE
ClientName LIKE '%harch%'
ORDER BY
DateOpened DESC
it hangs. What's weird about this is that PhaseName in this case is "Completed." Why would the REPLACE statement cause a problem? And why would LIKE be problematic in this case but not others? I'm on SQL Server 2017. Thanks in advance.

Related

Resulting nulls on full join not being replaced

I have a set of select queries using full join (required) and would like to replace the resulting nulls with something else (in the following example, it should be "empty").
For the first column (and all others, honestly) I have tried using isnull(), coallesce(), case when and even try_convert, but the result is always null. I'm ok with null, as in this particular case means that the results from the first query don't exist the second query, which is my goal.
There are following, identical queries, also full join 'd, so a line in the first query may not be in the second query but may be in the third of fourth queries.
Here is the select statement
SELECT *
FROM (SELECT Isnull(1, 'empty') AS SubGroup
, table2.lineintid AS OrderByThis2nd
, table2.HeaderStamp AS HeaderLink
, table2.linestamp AS LineID
, table2.lprocessname AS LineProcName
, table2.lprocessno AS LineProcNumber
, table2.productid AS ProdId
, table2.prodamount AS QTT
, table2.prodval AS UnitPrice
FROM table2 (nolock)
INNER JOIN table1 ON table2.headerstamp = table1.headerstamp
WHERE table1.lprocessname = 'Phase 1')Proc1L
FULL JOIN (SELECT Isnull(2, 'empty') AS SubGroup
, table2.lineintid AS OrderByThis2nd
, table2.linestamp AS LineID
, table2.prevlstamp AS PrecedingLine
, table2.lprocessname AS LineProcName
, table2.lprocessno AS LineProcNumber
, table2.productid AS ProdId
, table2.prodamount AS QTT
, table2.prodval AS UnitPrice
FROM table2 (nolock)
INNER JOIN table1 ON table2.headerstamp = table1.headerstamp
WHERE table1.lprocessname = 'Phase 2'
AND Year(table2.linedate) = '2018')Proc2L ON Proc1L.LineID = Proc2L.PrecedingLine
ORDER BY 1 DESC
, 2
This database is in MS SQL 2014.
Any ideas are appreciated. Thank you very much!
Try using ISNULL function in the outer query. Instead of
select * from
use
Select isnull(col1, 'x'), etc
from

SQL Server Query for required result

I am using SQL Server with my application.
The Table data is as following :
And I want result in following format:
I have tried with split function but its not working properly.
Is it possible to get such a result.
Please suggest.
Thank you.
Try this. I did not manage to get a single Not Req, it is like this ("Not Req/Not Req").
drop table if exists dbo.TableB;
create table dbo.TableB (
OldSPC varchar(100)
, old_freq varchar(100)
, NewSPC varchar(100)
, new_freq varchar(100)
);
insert into dbo.TableB(OldSPC, old_freq, NewSPC, new_freq)
values ('ADH,BAP', '7,7', 'ADH,BAP', '7,7')
, ('Not Req', 'Not Req', 'ADH,BAP', '7,7')
, ('BAP,EXT,ADL', '35,7,42', 'BAP,EXT,BAP,ADL', '21,7,35,42');
select
tt1.OldSPCOldFreq
, tt2.NewSPCNewFreq
from (
select
t.OldSPC, t.old_freq, t.NewSPC, t.new_freq
, STRING_AGG(t1.value + '/' + t2.value, ',') OldSPCOldFreq
from dbo.TableB t
cross apply (
select
ROW_NUMBER () over (order by t.OldSPC) as Rbr
, ss.value
from string_split (t.OldSPC, ',') ss
) t1
cross apply (
select
ROW_NUMBER () over (order by t.old_freq) as Rbr
, ss.value
from string_split (t.old_freq, ',') ss
) t2
where t1.Rbr = t2.Rbr
group by t.OldSPC, t.old_freq, t.NewSPC, t.new_freq
) tt1
inner join (
select
t.OldSPC, t.old_freq, t.NewSPC, t.new_freq
, STRING_AGG(t3.value + '/' + t4.value, ',') NewSPCNewFreq
from dbo.TableB t
cross apply (
select
ROW_NUMBER () over (order by t.NewSPC) as Rbr
, ss.value
from string_split (t.NewSPC, ',') ss
) t3
cross apply (
select
ROW_NUMBER () over (order by t.new_freq) as Rbr
, ss.value
from string_split (t.new_freq, ',') ss
) t4
where t3.Rbr = t4.Rbr
group by t.OldSPC, t.old_freq, t.NewSPC, t.new_freq
) tt2 on tt1.OldSPC = tt2.OldSPC
and tt1.old_freq = tt2.old_freq
and tt1.NewSPC = tt2.NewSPC
and tt1.new_freq = tt2.new_freq
As mentioned in comments, it might be easier for you to do it on front end, but it could be done in SQL Server as well.
Partial Rextester Demo
I didn't replicate your whole scenario but got it for 2 columns. To do it first of all, you need a unique identifier for each row. I am using a sequence number (1,2,3...).
Now refer to this answer, which uses recursive subquery to split csv to rows. Then I used XML PATH to change columns back to csv.
This is the query which is doing it for OLD SPC and OLD FREQ.
;with tmp(SEQ,OldSPCItem,OldSPC,OLD_FREQ_item,OLD_FREQ) as (
select SEQ, LEFT(OldSPC, CHARINDEX(',',OldSPC+',')-1),
STUFF(OldSPC, 1, CHARINDEX(',',OldSPC+','), ''),
LEFT(OLD_FREQ, CHARINDEX(',',OLD_FREQ+',')-1),
STUFF(OLD_FREQ, 1, CHARINDEX(',',OLD_FREQ+','), '')
from table1
union all
select SEQ, LEFT(OldSPC, CHARINDEX(',',OldSPC+',')-1),
STUFF(OldSPC, 1, CHARINDEX(',',OldSPC+','), ''),
LEFT(OLD_FREQ, CHARINDEX(',',OLD_FREQ+',')-1),
STUFF(OLD_FREQ, 1, CHARINDEX(',',OLD_FREQ+','), '')
from tmp
where OldSPC > ''
)
select seq,STUFF( (SELECT ',' + CONCAT(OldSPCItem,'/',OLD_FREQ_item) FROM TMP I
WHERE I.seq = O.seq FOR XML PATH('')),1,1,'') OLD_SPC_OLD_FREQ
from tmp O
GROUP BY seq
;
It will give you this output
+-----+------------------+
| seq | OLD_SPC_OLD_FREQ |
+-----+------------------+
| 1 | ADH/7,BAP/9 |
| 2 | NOT REQ/NOT REQ |
+-----+------------------+
What do you have to do now
- Find a way to generate a sequence number to uniquely identify each row. If you can use any column, use that instead of SEQ.
Similarly add logic for NEW_SPC and NEW_FREQ. (just copy paste LEFT and STUFF like in OLD_FREQ and change it for NEW_SPC and NEW_FREQ.
Replace multiple NOT REQ/ with '', so you will get only one NOT REQ. You can do it with replace function.
If you face any issue/error while doing so, add it to the Rexterster Demo and share the URL, we will check that.

SSRS “Subquery returned more than 1 value”

I'm using MS Visual Studio 2012. I'm having an issue with writing a subquery. This is the entire query as follows:
SELECT ACCOUNTNUM
, NAME
, ADDRESS
, PHONE
, TELEFAX
, INVOICEACCOUNT
, CUSTGROUP
, PAYMTERMID
, CURRENCY
, DIMENSION
, CELLULARPHONE
, STATISTICSGROUP
, PAYMMODE
, NAMEALIAS
, CONTACTPERSONID
, STREET
, PARTYID
, SEGMENTID
, TAXGROUP
, DATAAREAID
, ISNULL((
SELECT PERCENT1 AS DiscCount
FROM PRICEDISCTABLE
WHERE (DATAAREAID = CUSTTABLE.DATAAREAID)
AND (ACCOUNTRELATION = CUSTTABLE.ACCOUNTNUM)
), 0) / 100 AS DiscCount
, (
SELECT NAME
FROM CONTACTPERSON
WHERE (DATAAREAID = CUSTTABLE.DATAAREAID)
AND (CUSTACCOUNT = CUSTTABLE.ACCOUNTNUM)
AND (CONTACTPERSONID = CUSTTABLE.CONTACTPERSONID)
) AS ContactName
, (
SELECT PHONE
FROM CONTACTPERSON AS CONTACTPERSON_1
WHERE (DATAAREAID = CUSTTABLE.DATAAREAID)
AND (CUSTACCOUNT = CUSTTABLE.ACCOUNTNUM)
AND (CONTACTPERSONID = CUSTTABLE.CONTACTPERSONID)
) AS ContactPhone
, ISNULL((
SELECT STATGROUPNAME
FROM CUSTSTATISTICSGROUP
WHERE (DATAAREAID = CUSTTABLE.DATAAREAID)
AND (CUSTSTATISTICSGROUP = CUSTTABLE.STATISTICSGROUP)
), 0) AS StatisticsName
FROM CUSTTABLE
WHERE CUSTGROUP = #ty
AND DATAAREAID = N'OTN'
AND STATISTICSGROUP LIKE #ss;
and then I get the error
Subquery returned more than 1 value. This is not permitted when the
subquery follows =, !=, <, <= , >, >= or when the subquery is used as
an expression.
Where the issue comes from?
Issue is that one of your subqueries returns more than one value (HEY, ERROR DESCRIPTION SAYS THAT).
How to find which one?
Try commenting out each subquery in your select statement until your query works fine.
How to fix it?
That's probably the best case to use CROSS APPLY. That'd be your query:
SELECT ACCOUNTNUM
, NAME
, ADDRESS
, PHONE
, TELEFAX
, INVOICEACCOUNT
, CUSTGROUP
, PAYMTERMID
, CURRENCY
, DIMENSION
, CELLULARPHONE
, STATISTICSGROUP
, PAYMMODE
, NAMEALIAS
, CONTACTPERSONID
, STREET
, PARTYID
, SEGMENTID
, TAXGROUP
, DATAAREAID
, ISNULL(T1.DiscCount, 0) / 100 AS DiscCount
, T2.ContactName
, T3.ContactPhone
, ISNULL(T4, 0) AS StatisticsName
FROM CUSTTABLE
CROSS APPLY (
SELECT PERCENT1 AS DiscCount
FROM PRICEDISCTABLE
WHERE DATAAREAID = CUSTTABLE.DATAAREAID
AND ACCOUNTRELATION = CUSTTABLE.ACCOUNTNUM
) AS T1
CROSS APPLY (
SELECT NAME
FROM CONTACTPERSON
WHERE DATAAREAID = CUSTTABLE.DATAAREAID
AND CUSTACCOUNT = CUSTTABLE.ACCOUNTNUM
AND CONTACTPERSONID = CUSTTABLE.CONTACTPERSONID
) AS T2
CROSS APPLY (
SELECT PHONE
FROM CONTACTPERSON AS CONTACTPERSON_1
WHERE DATAAREAID = CUSTTABLE.DATAAREAID
AND CUSTACCOUNT = CUSTTABLE.ACCOUNTNUM
AND CONTACTPERSONID = CUSTTABLE.CONTACTPERSONID
) AS T3
CROSS APPLY (
SELECT STATGROUPNAME
FROM CUSTSTATISTICSGROUP
WHERE DATAAREAID = CUSTTABLE.DATAAREAID
AND CUSTSTATISTICSGROUP = CUSTTABLE.STATISTICSGROUP
) AS T4
WHERE CUSTGROUP = #ty
AND DATAAREAID = N'OTN'
AND STATISTICSGROUP LIKE #ss;
Also, these can be rewritten as simple INNER JOINS.
When encountering this error, try running the subqueries individually and if more than one record is returned then refine your conditions to ensure only one record is returned.
Of course, if more than one record is wanted then you need to change your query to use a join instead of a subquery.

How to pivot and get total amount each month

I have data like :
My table
My final results should be like this:
My SQL Statement:
SELECT 'Q'+cast([Month_Quarter] as varchar) Month_Quarter,COALESCE([Zugänge],0) Zugänge,COALESCE([Abgänge],0) Abgänge
FROM
(
SELECT DATEPART(QUARTER,[Monat]) [Month_Quarter],
[Zu-, Abgang],
Count(DISTINCT [Projektdefinition DB]) NoProjects
FROM AbZugänge
GROUP BY DATEPART(QUARTER,[Monat]), [Zu-, Abgang]
) proj
PIVOT (SUM(NoProjects) FOR [Zu-, Abgang] IN (Zugänge, Abgänge)) As pvt
WHERE [Month_Quarter] is not null
ORDER BY Month_Quarter
BUT with this statement I am getting the results without the Amount column Zugang and column Abgang:
How can I edit the statement to get the aggregation amount columns?
I suppose you can just wrap your query inside another select statement, then use GROUP BY. Something like this:
SELECT Month, SUM(ISNULL(column_name,0))
FROM (Your Query in here)
GROUP BY Month
Not sure I understand the point of the PIVOT in your original query. This looks like a typical aggregate is all that is required. See if this is what you need.
SELECT DATENAME(MONTH,Monat) [Month]
, sum(case when [Zu-, Abgang] = 'Zugänge' then [Zu-, Abgang] else 0 end) as Zugänge
, SUM(case when [Zu-, Abgang] = 'Abgänge' then [Zu-, Abgang] else 0 end) as Abgänge
, SUM([GWU aktuell]) as [GWU Total]
, SUM([GWU Planung aktuell]) AS [Plan Total]
, COUNT(DISTINCT [Projektdefinition DB]) NoProjects
FROM AbZugänge
group by DATENAME(MONTH,Monat)

OPTIMIZE FOR UNKNOWN when doing a UNION

So I have a few really slow queries in SP's I need to speed up, I have been using OPTIMIZE FOR UNKNOWN and seeing some dramatic increases in performance. I still have one query that really is slow and I want to apply this but it contains a UNION of 2 SQL Queries, so my question is do I apply the OPTIMIZE FOR UNKNOWN to both?
THIS IS A GREATLY SIMPLIFIED VERSION OF MY SP FOR CLARITY:
SELECT * FROM MyTable ManufacturerID=#ManufacturerID and tStamp > #tStamp
OPTION (OPTIMIZE FOR (#ManufacturerID UNKNOWN, #tStamp UNKNOWN))
UNION
SELECT * FROM MyTable ManufacturerID=#ManufacturerID
OPTION (OPTIMIZE FOR (#ManufacturerID UNKNOWN)
Here is the actual SP as it stand right now:
SELECT * FROM (
SELECT ROW_NUMBER() OVER(ORDER BY Products.ItemID) AS RowNum, *
FROM
(
SELECT Products.ProductID, Products.ItemID, Products.ManufacturerID,
CategoryID = NULL, CategoryName = NULL,
CategoryProductID = NULL, Products.ItemName, Products.Description, Products.Notes,
Products.Dimensions, Products.BasePrice, Products.OrderMinimumQuantity,
ContainerMinimumQuantity =
CASE COALESCE(Products.ContainerMinQty, 0)
WHEN 0 THEN Products.OrderMinimumQuantity
ELSE Products.ContainerMinQty
END
, Products.OrderMultipleQuantity, Products.OnHandQuantity,
Products.Category, Products.IntroDate, Products.BackOrderDate, Products.UPC, Products.PriceLevel1, Products.PriceLevel2, Products.PriceLevel3,
Products.PriceLevel4, Products.PriceLevel5, Products.PriceLevel6, Products.PriceLevel7, Products.PriceLevel8, Products.PriceLevel9, Products.PieceBox,
Products.Cubes, Products.UnitOfMeasure, Products.UDF1, Products.UDF2, Products.UDF3, Products.UDF4, Products.UDF5, Products.AdditionalImageCount,
PhotoName= LOWER(Products.PhotoName), Products.Discontinued, Products.ModifiedOn,
Products.IsDeleted, Products.PriceLevel10, Products.PriceLevel11, Products.PriceLevel12, Products.PriceLevel13,
Products.PriceLevel14, Products.PriceLevel15, Products.PriceLevel16, Products.PriceLevel17, Products.PriceLevel18, Products.PriceLevel19, Products.PriceLevel20,
Products.Weight, Products.DimensionsMetric, Products.Source, Products.InventoryStatus, Products.CatalogCode, Products.CatalogName,
SortOrder = NULL,
Products.reportCategory,Products.additionalPhotos,Products.udf6,Products.udf7,Products.udf8,
Products.udf9,Products.udf10,Products.udf11,Products.udf12,Products.udf13,Products.udf14,Products.udf15,Products.udf16,
Products.udf17,Products.udf18,Products.udf19,Products.udf20, Products.showRelatedFor,Products.showChildFor
FROM
CategoryProducts (nolock) RIGHT OUTER JOIN
Products (nolock) ON CategoryProducts.ManufacturerID = Products.ManufacturerID AND CategoryProducts.ItemID = Products.ItemID
WHERE (Products.ManufacturerID = #ManufacturerID)
AND
(Products.ModifiedOn > #tStamp ) AND ((CategoryProducts.IsDeleted = 1) OR (CategoryProducts.IsDeleted IS NULL)
)
UNION
SELECT Products.ProductID, Products.ItemID, Products.ManufacturerID, Categories.CategoryID, Categories.CategoryName, CategoryProducts.CategoryProductID, Products.ItemName, Products.Description, Products.Notes,
Products.Dimensions, Products.BasePrice, Products.OrderMinimumQuantity,
ContainerMinimumQuantity =
CASE COALESCE(Products.ContainerMinQty, 0)
WHEN 0 THEN Products.OrderMinimumQuantity
ELSE Products.ContainerMinQty
END
, Products.OrderMultipleQuantity, Products.OnHandQuantity,
Products.Category, Products.IntroDate, Products.BackOrderDate, Products.UPC, Products.PriceLevel1, Products.PriceLevel2, Products.PriceLevel3,
Products.PriceLevel4, Products.PriceLevel5, Products.PriceLevel6, Products.PriceLevel7, Products.PriceLevel8, Products.PriceLevel9, Products.PieceBox,
Products.Cubes, Products.UnitOfMeasure, Products.UDF1, Products.UDF2, Products.UDF3, Products.UDF4, Products.UDF5, Products.AdditionalImageCount,
PhotoName= LOWER(Products.PhotoName), Products.Discontinued, Products.ModifiedOn,
CategoryProducts.IsDeleted, Products.PriceLevel10, Products.PriceLevel11, Products.PriceLevel12, Products.PriceLevel13,
Products.PriceLevel14, Products.PriceLevel15, Products.PriceLevel16, Products.PriceLevel17, Products.PriceLevel18, Products.PriceLevel19, Products.PriceLevel20,
Products.Weight, Products.DimensionsMetric, Products.Source, Products.InventoryStatus, Products.CatalogCode, Products.CatalogName,
CategoryProducts.SortOrder,
Products.reportCategory,Products.additionalPhotos,Products.udf6,Products.udf7,Products.udf8,
Products.udf9,Products.udf10,Products.udf11,Products.udf12,Products.udf13,Products.udf14,Products.udf15,Products.udf16,
Products.udf17,Products.udf18,Products.udf19,Products.udf20, Products.showRelatedFor,Products.showChildFor
FROM Categories (nolock) INNER JOIN
CategoryProducts (nolock) ON Categories.CategoryID = CategoryProducts.CategoryID INNER JOIN
Products (nolock) ON CategoryProducts.ManufacturerID = Products.ManufacturerID AND CategoryProducts.ItemID = Products.ItemID
WHERE (Products.ManufacturerID = #ManufacturerID)
AND
(Products.ModifiedOn > #tStamp OR CategoryProducts.ModifiedOn > #tStamp)
) AS Products
) AS C WHERE RowNum >= #StartRow AND RowNum <= #EndRow ORDER BY ItemID, ManufacturerID
OPTION (OPTIMIZE FOR (#ManufacturerID UNKNOWN, #StartRow UNKNOWN, #EndRow UNKNOWN, #tStamp UNKNOWN))
From Books Online (Query Hints):
Query hints specify that the indicated hints should be used throughout
the query. They affect all operators in the statement. If UNION is
involved in the main query, only the last query involving a UNION
operation can have the OPTION clause.
So that's pretty explicit that you can only use OPTION once, not twice like in your example.
That makes sense, since even though there are two SELECT statements put together, SQL Server will still treat it as one overall statement for the purposes of compilation and optimization.
This does mean that if you want to use different hints in the different statements that make up the UNION you'll have to go about it a different way, e.g. using TEMP tables to store the interim results.
So, in your specific example, even though #tStamp is only in the first SELECT statement, you can still reference it in the one OPTION clause as required.
Try this one -
SELECT
p.ProductID
, RowNum = ROW_NUMBER() OVER(ORDER BY p.ItemID)
, p.ItemID
, p.ManufacturerID
, CategoryID = NULL
, CategoryName = NULL
, CategoryProductID = NULL
, p.ItemName
, p.[Description]
, p.Notes
, p.Dimensions
, p.BasePrice
, p.OrderMinimumQuantity
, ContainerMinimumQuantity =
CASE WHEN ISNULL(p.ContainerMinQty, 0) = 0
THEN p.OrderMinimumQuantity ELSE p.ContainerMinQty
END
, p.OrderMultipleQuantity
, p.OnHandQuantity
, p.category
, p.IntroDate
, p.BackOrderDate
, p.UPC
...
, p.PieceBox
, p.Cubes
, p.UnitOfMeasure
, p.UDF1, p.UDF2, p.UDF3
, p.UDF4, p.UDF5
, p.AdditionalImageCount
, PhotoName = LOWER(p.PhotoName)
, p.Discontinued
, p.ModifiedOn
, p.IsDeleted
...
, p.[Weight]
, p.DimensionsMetric
, p.[Source]
, p.InventoryStatus
, p.CatalogCode
, p.CatalogName
, SortOrder = NULL
, p.reportCategory
, p.additionalPhotos
....
, p.showRelatedFor
, p.showChildFor
FROM dbo.Products p WITH(NOLOCK)
--LEFT JOIN (
-- SELECT *
-- FROM dbo.CategoryProducts cp WITH(NOLOCK)
-- WHERE ISNULL(cp.IsDeleted, 1) = 1
--) cp ON cp.ManufacturerID = p.ManufacturerID AND cp.ItemID = p.ItemID
WHERE p.ManufacturerID = #ManufacturerID
AND p.ModifiedOn > #tStamp

Resources