SQL Invalid data is showing - sql-server

t0212_1 t0212_2
884999999 GCP-9 Company A
8849999 GCP-7 Company B
#val = 884999999
Here's my query :
Select * Company
WHERE t0212_1= (LEFT(CONVERT(BIGINT,#val),convert(int,substring('GCP-9',5,2)))) OR
t0212_1= LEFT(CONVERT(BIGINT,#val),convert(int,substring('GCP-7',5,2)))
When I searched 8849999 , 8849999 shows(this is RIGHT).
When I searched 884999999 , 884999999 shows(this is RIGHT) and 8849999 shows(WRONG).
What to do, please help
Thanks,
If you dont understand my very short explanation you can verify it to me.

Your filteration is either 7 or 9 characters from the input (DECLARE #val INT = 884999999)
should match the column (t0212_1) value.
As per your filter, you would get two records since the two records matched on your filteration.
You can use this SQL
SELECT *
FROM #Company
WHERE t0212_1 = (LEFT(CONVERT(BIGINT, #val), convert(INT, substring(t0212_2, 5, 2))))

Related

Microsoft SQL Server: wrong query execution plan taking too long

This is on Windows SQL Server Cluster.
Query is coming from 3rd party application so I can not modify the query permanently.
Query is:
DECLARE #FromBrCode INT = 1001
DECLARE #ToBrCode INT = 1637
DECLARE #Cdate DATE = '31-mar-2017'
SELECT
a.PrdCd, a.Name, SUM(b.Balance4) as Balance
FROM
D009021 a, D010014 b
WHERE
a.PrdCd = LTRIM(RTRIM(SUBSTRING(b.PrdAcctId, 1, 8)))
AND substring(b.PrdAcctId, 9, 24) = '000000000000000000000000'
AND a.LBrCode = b.LBrCode
AND a.LBrCode BETWEEN #FromBrCode AND #ToBrCode
AND b.CblDate = (SELECT MAX(c.CblDate)
FROM D010014 c
WHERE c.PrdAcctId = b.PrdAcctId
AND c.LBrCode = b.LBrCode
AND c.CblDate <= #Cdate)
GROUP BY
a.PrdCd, a.Name
HAVING
SUM(b.Balance4) <> 0
ORDER BY
a.PrdCd
This particular query is taking too much time to complete execution. The same problem happens on a different SQL Server.
No table lock was found, processor and memory usage is normal while the query is running.
Normal "select top 1000" working and showing output instantly in both tables (D009021, D010014)
Reindex and rebuild / update stats done in both tables but problem did not resolve (D009021, D010014)
The same query is working if we reduce number of branch but slowly
(
DECLARE #FromBrCode INT =1001
DECLARE #ToBrCode INT =1001
)
The same query is working faster giving output within 2 mins if we replace any one variable and use the value directly
AND a.LBrCode BETWEEN #FromBrCode AND #ToBrCode
changed to
AND a.LBrCode BETWEEN 1001 AND #ToBrCode
The same query is working faster and giving output within 2 mins if we add "OPTION (RECOMPILE)" at end
I tried to clean cache query execution plan and optimized new one but problem still exists
Found that the query estimate plan and actual execution plan are different (see screenshots)
Table D010014 is aliased twice once as b and once as c
the they are joined to the same table.
Try toto remove the sub query below and create a temp table to store
the values you need. I added * to the fields you self join
SELECT MAX(c.CblDate)
FROM D010014 c
WHERE c.PrdAcctId = b.PrdAcctId
AND c.LBrCode = b.LBrCode
AND c.CblDate <= #Cdate
if you cant do that then try
SELECT TOP 1 c.CblDate
FROM D010014 c
WHERE c.PrdAcctId = b.PrdAcctId
AND c.LBrCode = b.LBrCode
AND c.CblDate <= #Cdate
ORDER BY c.CblDate DESC

Count the 'X' then arrange the value as row in SQL

I have a table in SQL that have many columns which the value of each columns in every row is either ' ' or 'X'. I need to count this 'X' for every columns which can be done by following code;
SELECT COUNT(GVI0) AS GVI0, COUNT(GVI1) AS GVI1, COUNT(GVI2) AS GVI2
FROM dbo.HullInspectionProgram
WHERE (StructureEntry='1' AND Year='2016')
The result of the query is;
GVI0 NDT0 GVI1 NDT1 GVI2 NDT2
11 11 2 4 11 11
However, (in my understanding) in order for this count value to be bind into ASP.net Chart Control with multiple series name 'GVI' and 'NDT', I need to make the column into row for the DataTable.
I try to use UNPIVOT in SQL like this;
SELECT GVI0Count
FROM (
SELECT COUNT(GVI0) AS GVI0, COUNT(GVI1) AS GVI1, COUNT(GVI2) AS GVI2
FROM dbo.HullInspectionProgram
WHERE (StructureEntry='1' AND Year='2016')
)
UNPIVOT (GVI0Count FOR ListOfColumns IN (GVI0)) AS unpivott
but it seem that the code is wrong.
How do I do this?
I think the following might work for you. At least, as a start.
SELECT *
FROM (
SELECT COUNT(GVI0) AS GVI0, COUNT(GVI1) AS GVI1, COUNT(GVI2) AS GVI2
FROM dbo.HullInspectionProgram
WHERE (StructureEntry='1' AND Year='2016')
) P
UNPIVOT (GVI0Count FOR ListOfColumns IN (GVI0, GVI1, GVI2)) AS unpivott

Missing data row in NOT IN clause

I just realised that my Auto-Price Calculation doesn't fill the Prices for ListID 4.
I inserted the Prices from the SELECT shown below.
For bugg research I executed the SELECT without the WHERE part and it shows me the example data row.
I can't find the error though, why it is not shown in the complete select (it has no entry with ListID = 4).
Someone can see my mistake?
Edit: Just tried the subselect alone, it shows no rows for the requested article. Why is the NOT IN clause unaffected by this fact?
Most likely, it's because of how you are combining the artikelnummer and the auspraegungID.
I do not think you have accounted for that fact that '100' + '0' is idential to '10' + '00'.
Instead of trying to merge two fields into one, perhaps try the following?
SELECT
*
FROM
#allArticles AS allArticles
WHERE
Artikelnummer = 'IT-810260'
AND NOT EXISTS (SELECT *
FROM KHKPreisListenArtikel
WHERE ListeID = 4
AND Artikelnummer = allArticles.Artikelnummer
AND Auspraegung = allArticles.Auspraegung
)
If that still doesn't work, then you must have corresponding records in that other table, find them like this...
SELECT
*
FROM
#allArticles AS allArticles
INNER JOIN
KHKPreisListenArtikel AS Preis
ON Preis.ListeID = 4
AND Preis.Artikelnummer = allArticles.Artikelnummer
AND Preis.Auspraegung = allArticles.Auspraegung
WHERe
allArticles.Artikelnummer = 'IT-810260'
PLEASE ALSO NOTE
Please don't include images of code, please copy the code, so that we can copy it too.
Especially when the tables/fields are in another language...
EDIT
Here is a query that will show the cause of your original query to fail.
SELECT
*
FROM
#allArticles AS allArticles
INNER JOIN
KHKPreisListenArtikel AS Preis
ON Preis.ListeID = 4
AND Preis.Artikelnummer + CONVERT(VARCHAR(50), Preis.Auspraegung)
=
allArticles.Artikelnummer + CONVERT(VARCHAR(50), allArticles.Auspraegung)
WHERE
allArticles.Artikelnummer = 'IT-810260'

Yet another subquery issue

Hello from an absolute beginner in SQL!
I have a field I want to populate based on another table. For this I have written this query, which fails with: Msg 512, Level 16, State 1, Line 1
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
The statement has been terminated.
oK, here goes:
Update kre.CustomerOrderLineCopy
SET DepNo = (SELECT customerordercopy.DepNo
FROM kre.CustomerOrderCopy , kre.CustomerOrderLineCopy
WHERE CustomerOrderLineCopy.OrderCopyNo =kre.CustomerOrderCopy.OrderCopyNo)
WHERE CustomerOrderLineCopy.OrderCopyNo = (SELECT CustomerOrderCopy.OrderCopyNo
FROM kre.CustomerOrderCopy, kre.CustomerOrderLineCopy
WHERE kre.CustomerOrderLineCopy.OrderCopyNo = kre.CustomerOrderCopy.OrderCopyNo)
What I'm trying to do is to change DepNo in CustomerOrderLineCopy, with the value in DepNo in CustomerOrderCopy - based on the same OrderCopyNo in both tables.
I'm open for all suggestion.
Thanks,
ohalvors
If you just join the tables together the update is easier:
UPDATE A SET A.DepNo = B.DepNo
FROM kre.CustomerOrderLineCopy A
INNER JOIN kre.CustomerOrderCopy B ON A.OrderCopyNo = B.OrderCopyNo
The problem is that at least one of your sub queries return more than one value. Think about this:
tablePerson(name, age)
Adam, 11
Eva, 11
Sven 22
update tablePerson
set name = (select name from tablePerson where age = 11)
where name = 'Sven'
Which is equivalent to: set Sven's name to Adam and Eva. Which is not possible.
If you want to use sub queries, either make sure your sub queries can only return one value or force one value by using:
select top 1 xxx from ...
This may be enough to quieten it down:
Update kre.CustomerOrderLineCopy
SET DepNo = (SELECT customerordercopy.DepNo
FROM kre.CustomerOrderCopy --, kre.CustomerOrderLineCopy
WHERE CustomerOrderLineCopy.OrderCopyNo =kre.CustomerOrderCopy.OrderCopyNo)
WHERE CustomerOrderLineCopy.OrderCopyNo = (SELECT CustomerOrderCopy.OrderCopyNo
FROM kre.CustomerOrderCopy --, kre.CustomerOrderLineCopy
WHERE kre.CustomerOrderLineCopy.OrderCopyNo = kre.CustomerOrderCopy.OrderCopyNo)
(Where I've commented out kre.CustomerOrderLineCopy in the subqueries) That is, you were hopefully trying to correlate these subqueries with the outer table - not introduce another instance of kre.CustomerOrderLineCopy.
If you still get an error, then you still have multiple rows in kre.CustomerOrderCopy which have the same OrderCopyNo. If that's so, you need to give us (and SQL Server) the rules that you want to apply for how to select which row you want to use.
The danger of switching to the FROM ... JOIN form shown in #Avitus's answer is that it will no longer report if there are multiple matching rows - it will just silently pick one of them - which one is never made clear.
Now I look at the query again, I'm not sure it even needs a WHERE clause now. I think this is the same:
Update kre.CustomerOrderLineCopy
SET DepNo = (
SELECT customerordercopy.DepNo
FROM kre.CustomerOrderCopy
WHERE CustomerOrderLineCopy.OrderCopyNo = kre.CustomerOrderCopy.OrderCopyNo)

Oracle split text into multiple rows

Inside a varchar2 column I have text values like :
aaaaaa. fgdfg.
bbbbbbbbbbbbbb ccccccccc
dddddd ddd dddddddddddd,
asdasdasdll
sssss
if i do select column from table where id=... i get the whole text in a single row, normally.
But i would like to get the result in multiple rows, 5 for the example above.
I have to use just one select statement, and the delimiters will be new line or carriage return (chr(10), chr(13) in oracle)
Thank you!
Like this, maybe (but it all depends on the version of oracle you are using):
WITH yourtable AS (SELECT REPLACE('aaaaaa. fgdfg.' ||chr(10)||
'bbbbbbbbbbbbbb ccccccccc ' ||chr(13)||
'dddddd ddd dddddddddddd,' ||chr(10)||
'asdasdasdll ' ||chr(13)||
'sssss '||chr(10),chr(13),chr(10)) AS astr FROM DUAL)
SELECT REGEXP_SUBSTR ( astr, '[^' ||chr(10)||']+', 1, LEVEL) data FROM yourtable
CONNECT BY LEVEL <= LENGTH(astr) - LENGTH(REPLACE(astr, chr(10))) + 1
see: Comma Separated values in Oracle
The answer by Kevin Burton contains a bug if your data contains empty lines.
The adaptation below, based on the solution invented here, works. Check that post for an explanation on the issue and the solution.
WITH yourtable AS (SELECT REPLACE('aaaaaa. fgdfg.' ||chr(10)||
'bbbbbbbbbbbbbb ccccccccc ' ||chr(13)||
chr(13)||
'dddddd ddd dddddddddddd,' ||chr(10)||
'asdasdasdll ' ||chr(13)||
'sssss '||chr(10),chr(13),chr(10)) AS astr FROM DUAL)
SELECT REGEXP_SUBSTR ( astr, '([^' ||chr(10)||']*)('||chr(10)||'|$)', 1, LEVEL, null, 1) data FROM yourtable
CONNECT BY LEVEL <= LENGTH(astr) - LENGTH(REPLACE(astr, chr(10))) + 1;

Resources