Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I have variable declared like this
DECLARE #Customer_No VARCHAR(MAX)
SET #Customer_No = 'Z110073574;Z110027464;Z110229752;Z110274156;Z110170566;Z110102837;Z110074199'
The query contains condition
WHERE ((#Customer_No = '') OR ([Customer No_] IN (SELECT [No_] FROM Customer)))
If the variable #Customer_No can contains blank value (''), filtering should be skipped. In case the variable contains customers separated by semicolons, the string is parsed into table Customer and the query is filtered by values in Customer table.
The query takes 15 minutes to run. If I use just the second condition, it takes about 50 seconds.
WHERE [Customer No_] IN (SELECT [No_] FROM Customer)
I don't get it. How is this possible? Any solution? Explanation?
Thank you.
Edit: Query
SELECT DET.[Cust_ Ledger Entry No_]
, DET.[Amount]
, DET.[Entry Type]
, CLE.[Document No_]
FROM [dbo].[Company$Cust_ Ledger Entry] CLE
LEFT JOIN [dbo].[Company$Detailed Cust_ Ledg_ Entry] DET ON CLE.[Entry No_] = DET.[Cust_ Ledger Entry No_]
WHERE ((#Customer_No = '') OR (DET.[Customer No_] IN (SELECT [No_] FROM Customer)))
AND (DET.[Entry Type] = 1 OR DET.[Entry Type] = 2)
AND (CLE.[Due Date] >= #FromDueDate AND CLE.[Due Date] <= #ToDueDate)
AND CLE.[Posting Date] <= #ToDate
I think you can simply the query without loss of integrity to the following. Like Aaron said, can you post a query plan?
SELECT
DET.[Cust_ Ledger Entry No_],
DET.[Amount],
DET.[Entry Type],
CLE.[Document No_]
FROM
[dbo].[Company$Cust_ Ledger Entry] CLE
LEFT JOIN
[dbo].[Company$Detailed Cust_ Ledg_ Entry] DET
ON
CLE.[Entry No_] = DET.[Cust_ Ledger Entry No_]
WHERE
( #FAS_No = '' OR DET.[Customer No_] IN (SELECT [No_] FROM Customer) )
AND DET.[Entry Type] in (1, 2)
AND CLE.[Due Date] >= #FromDueDate
AND CLE.[Due Date] <= #ToDueDate
AND CLE.[Posting Date] <= #ToDate
It's not easy to pinpoint the exact problem without more information (table structure, # of rows, etc). However, one thing for sure is the the use of OR in TSQL reduces overall performance. If there is a way to use an AND instead of an OR than it's recommended you do so.
what you can always do it use an IF statement that check if the variable is empty. If not, you use the SELECT with the WHERE. If it is empty, you use the SELECT without the WHERE.
Another thing to check might be your indexes. That can speed things a little.
The DET in the where is killing the left so might as well join
If you pull conditions into the join then the query optimizer seems to do a better
I think this gives a the query optimizer a better chance
SELECT DET.[Cust_ Ledger Entry No_]
, DET.[Amount]
, DET.[Entry Type]
, CLE.[Document No_]
FROM [dbo].[Company$Cust_ Ledger Entry] CLE
JOIN [dbo].[Company$Detailed Cust_ Ledg_ Entry] DET
ON CLE.[Entry No_] = DET.[Cust_ Ledger Entry No_]
AND ( DET.[Entry Type] IN (1,2) )
AND ( CLE.[Due Date] >= #FromDueDate AND CLE.[Due Date] <= #ToDueDate )
AND CLE.[Posting Date] <= #ToDate
JOIN Customer
ON #Customer_No = ''
OR DET.[Customer No_] = Customer.[No_]
And try hints
I would start with INNER MERGE JOIN Customer
And please [NO_] is declared as a PK
I think you can reduce the performance by writing in
USE CTE for - (SELECT [No_] FROM Customer)
Join cte with the main table which will give you performance
Related
I am using inner join in query but I want Subquery instead of join
select [Document No_] as DocumentNo,
ledger.[Posting Date] as Date,
[Sales (LCY)] as Amount,
header.[Customer Reference] as PONo
from [Uneek Clothing Company Ltd$Cust_ Ledger Entry] ledger
inner join [Uneek Clothing Company Ltd$Sales Invoice Header] header on ledger.[Entry No_]=header.[Cust_ Ledger Entry No_]
where [Customer No_] = 'DRC01'
and [Document Type]=2
and [Sales (LCY)]!=0
and ledger.[Posting Date] between '01/01/2019' and '12/31/2019'
order by [Sales (LCY)] asc offset 0 ROWS FETCH NEXT 20 ROWS ONLY
[Entry No_] is foreign key in [Uneek Clothing Company Ltd$Sales Invoice Header] with name [Cust_ Ledger Entry No_]
if you really want to drop the join and use a subquery instead,
it will look something like this.
Since you did not use an table alias for all columns, I had to assume that no other column of table in the subquery is used anywhere else. If that is not the case then this will not work
It will also only work if the subquery returns no more then 1 row, otherwise a subquery cannot be used at all
select [Document No_] as DocumentNo,
ledger.[Posting Date] as Date,
[Sales (LCY)] as Amount,
( select header.[Customer Reference]
from [Uneek Clothing Company Ltd$Sales Invoice Header] header
where ledger.[Entry No_] = header.[Cust_ Ledger Entry No_]
) as PONo
from [Uneek Clothing Company Ltd$Cust_ Ledger Entry] ledger
where [Customer No_] = 'DRC01'
and [Document Type]=2
and [Sales (LCY)]!=0
and ledger.[Posting Date] between '01/01/2019' and '12/31/2019'
order by [Sales (LCY)] asc
offset 0 ROWS FETCH NEXT 20 ROWS ONLY
When trying to convert a datetime field to get rid of NULL's I am getting the error that the datetime cannot be converted.
This query is populating another database where the column datatype is date.
This job runs perfectly fine when not scheduled, but results in an error during the scheduled insert job.
Any ideas?
, (SELECT
CASE
WHEN MIN([Discount Ledger].[Posting Date]) IS NOT NULL
THEN CONVERT(VARCHAR(50), MIN([Discount Ledger].[Posting Date]), 121)
ELSE '-'
END
FROM
[Wings$Discount Ledger Entry] AS "Discount Ledger"
LEFT JOIN
[Wings$Periodic Discount] AS "MixMatchHeader" ON [Discount Ledger].[Offer No_] = [MixMatchHeader].[No_]
LEFT JOIN
[Wings$Periodic Discount Line] AS "MixMatch" ON [MixMatchHeader].[No_] = [MixMatch].[Offer No_]
LEFT JOIN
[Wings$Item_Special Group Link] AS "Special Group" ON [MixMatch].[No_] = [Special Group].[Special Group Code]
LEFT JOIN
[Wings$Store Price Group] AS "Store Price Group" ON [MixMatch].[Price Group] = [Store Price Group].[Price Group Code]
WHERE
[MixMatch].[No_] = [Item Ledger].[Item No_]
AND [MixMatch].[Variant Code] = [Item Ledger].[Variant Code]
AND [Store Price Group].[Store] = [Item Ledger].[Location Code]) AS "Discount Start Date"
You can do this using ISNULL. Since you are looking for the MIN date, I will use GETDATE() as the argument/replacement value for NULL. Unless your data has future dates, then GETDATE() should function as the MAX value. Unless you want the CASE statement to evaluate the NULL values as the MIN. In that case, you can use an empty string '' or '1900-01-01' instead of GETDATE().
, (SELECT
CASE
WHEN
MIN([Discount Ledger].[Posting Date]) IS NOT NULL
THEN CONVERT(varchar(50),MIN(ISNULL([Discount Ledger].[Posting Date],GETDATE())),121)
ELSE '-'
END
FROM [Wings$Discount Ledger Entry] AS "Discount Ledger"
LEFT JOIN [Wings$Periodic Discount] AS "MixMatchHeader" ON [Discount Ledger].[Offer No_] = [MixMatchHeader].[No_]
LEFT JOIN [Wings$Periodic Discount Line] AS "MixMatch" ON [MixMatchHeader].[No_] = [MixMatch].[Offer No_]
LEFT JOIN [Wings$Item_Special Group Link] AS "Special Group" ON [MixMatch].[No_] = [Special Group].[Special Group Code]
LEFT JOIN [Wings$Store Price Group] AS "Store Price Group" ON [MixMatch].[Price Group] = [Store Price Group].[Price Group Code]
WHERE [MixMatch].[No_] = [Item Ledger].[Item No_] AND [MixMatch].[Variant Code] = [Item Ledger].[Variant Code] AND [Store Price Group].[Store] = [Item Ledger].[Location Code])
AS "Discount Start Date"
Hard to explain problem here :)
I need to get a new column I have the amount of lines
F.E. "RIT-17000263-T: 1" would have an extra column "Total Sequences": '9'
"RIT-17000264-T: 1" would be "Total Sequences": '2'
Any help is welcome!:
SELECT DISTINCT
CONCAT(R.[Trip No_],'-', CONCAT('T: ', LEFT(R.[Partial trip Line No_],1))) AS 'TRIP',
R.[File] AS 'FILE',
R.[Sequence No_] AS 'SEQUENCE IN PTRIP'
FROM
[Route] AS R
WHERE
(R.[Trip No_] = 'RIT-17000263'
OR R.[Trip No_] = 'RIT-17000264')
GROUP BY
CONCAT(R.[Trip No_], '-', CONCAT('T: ', LEFT(R.[Partial trip Line No_],1))),
R.[File], R.[Sequence No_]
Perhaps wrap it in a CTE...
with cte as(
SELECT DISTINCT
CONCAT(R.[Trip No_],'-', CONCAT('T: ', LEFT(R.[Partial trip Line No_],1))) AS 'TRIP',
R.[File] AS 'FILE',
R.[Sequence No_] AS 'SEQUENCE IN TRIP'
FROM
[Route] AS R
WHERE
(R.[Trip No_] = 'RIT-17000263'
OR R.[Trip No_] = 'RIT-17000264')
GROUP BY
CONCAT(R.[Trip No_], '-', CONCAT('T: ', LEFT(R.[Partial trip Line No_],1))),
R.[File], R.[Sequence No_])
select
c.TRIP,
c.[FILE],
c.[SEQUENCE IN TRIP],
c2.CT as [Total Sequences]
from
cte c
join (select TRIP, count(TRIP) as CT from cte group by TRIP) c2 on c2.TRIP = c.TRIP
Thank for your help and reading, I have the below query and I don't understand why this error message occurs:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near 'Price'
I am able to query this data column (Wholesale Price) in a standalone query. I'm using SQL Server 2005 Management Studio .
SELECT
ILE.[Location Code],
ILE.SUM(Quantity) AS "Transfer Qty",
PP.SUM(Wholesale Price) AS "Transfer Cost (HK)"
FROM
[DB].[dbo].[Company$Item Ledger Entry] ILE
INNER JOIN
[DB].[dbo].[Company$Purchase Price] PP ON ILE.[Item No_] = PP.[Item No_]
AND ILE.[Variant Code] = PP.[Variant Code]
WHERE
ILE.[Entry Type] = '4'
AND ILE.[Location Code] NOT LIKE '%STAFF%'
AND ILE.[Location Code] NOT LIKE 'WHSPACKAGE'
AND ILE.[Location Code] NOT LIKE 'WHS'
GROUP BY
ILE.[Location Code], ILE.[Quantity], PP.[Wholesale Price]
ORDER BY
[Location Code]
Thanks!
Regards,
Patrick
In SQL, you have to escape names that contain special characters -- and spaces are special characters. Because reading and writing code that has lots of square braces is cumbersome, the general advice is to avoid using such names.
In your case, you are missing the square braces:
SELECT ILE.[Location Code], ILE.Sum(Quantity) as "Transfer Qty",
Sum(PP.[Wholesale Price]) as "Transfer Cost (HK)"
FROM [DB].[dbo].[Company$Item Ledger Entry] ILE INNER JOIN
[DB].[dbo].[Company$Purchase Price] PP
ON ILE.[Item No_] = PP.[Item No_] AND
ILE.[Variant Code] = PP.[Variant Code]
Where ILE.[Entry Type] = '4' AND
ILE.[Location Code] NOT LIKE '%STAFF%' AND
ILE.[Location Code] NOT LIKE 'WHSPACKAGE' AND
ILE.[Location Code] NOT LIKE 'WHS'
Group by ILE.[Location Code], ILE.[Quantity]
Order by [Location Code];
In addition:
PP.SUM() doesn't make sense. The table alias goes with the column name.
Putting the wholesale price in the GROUP BY doesn't make sense. You want to aggregate the value, so it usually wouldn't go there.
Check this select statement for your error
SELECT
ILE.[Location Code],
ILE.SUM(Quantity) AS "Transfer Qty",
PP.SUM([Wholesale Price]) AS "Transfer Cost (HK)"--Error line
Thank you so much! Gordon!
Both SUM statement should be wording this format,
Sum(ILE.[Quantity] and Sum(PP.[Wholesale Price])
SELECT ILE.[Location Code], Sum(ILE.[Quantity]) as "Transfer Qty",
Sum(PP.[Wholesale Price]) as "Transfer Cost (HK)"
FROM [Dummy-28-Oct-2016].[dbo].[TEST ENV$Item Ledger Entry] ILE
INNER JOIN [Dummy-28-Oct-2016].[dbo].[TEST ENV$Purchase Price] PP
ON ILE.[Item No_] = PP.[Item No_]
AND ILE.[Variant Code] = PP.[Variant Code]
Where ILE.[Entry Type] = '4'
AND ILE.[Location Code] NOT LIKE '%STAFF%'
AND ILE.[Location Code] NOT LIKE 'WHSPACKAGE'
AND ILE.[Location Code] NOT LIKE 'WHS'
Group by ILE.[Location Code], ILE.[Quantity]
Order by [Location Code];
I'm working on aging report for accounts over 30 days and I am joining the "Comment" table because AP wants to see the most recent comment if it exists for a customer.
The comment table can have multiple rows for the same customer for each comment that is attached to that customer with the first record being the oldest comment.
When I join the tables everything works, but it returns the first comment not the latest.
How can I get it to to look for multiple rows for the same customer and then return the most recent comment?
*Note - The comment table does not have dates just a field the starts at 1000 and increases for each new comment row
This is what i have right now:
SELECT
dbo.[Pioneer-CO$Purchase Header].No_,
dbo.[Pioneer-CO$Purchase Line].[Amt_ Rcd_ Not Invoiced],
dbo.[Pioneer-CO$Purch_ Rcpt_ Header].[Posting Date],
dbo.[Pioneer-CO$Comment Line].[Comment],
dbo.[Pioneer-CO$Purchase Header].[Sell-to Customer No_]
FROM
dbo.[Pioneer-CO$Purchase Header]
INNER JOIN
dbo.[Pioneer-CO$Purchase Line] ON dbo.[Pioneer-CO$Purchase Header].No_ = dbo.[Pioneer-CO$Purchase Line].[Document No_]
INNER JOIN
dbo.[Pioneer-CO$Purch_ Rcpt_ Header] ON dbo.[Pioneer-CO$Purchase Header].No_ = dbo.[Pioneer-CO$Purch_ Rcpt_ Header].[Order No_]
INNER JOIN
dbo.[Pioneer-CO$Comment Line] ON dbo.[Pioneer-CO$Purchase Header].[Sell-to Customer No_] = dbo.[Pioneer-CO$Comment Line].[No_]
WHERE
(dbo.[Pioneer-CO$Purch_ Rcpt_ Header].[Posting Date] < DATEADD(day, - 30, GETDATE()))
GROUP BY
dbo.[Pioneer-CO$Purchase Header].No_,
dbo.[Pioneer-CO$Purchase Line].[Amt_ Rcd_ Not Invoiced],
dbo.[Pioneer-CO$Purch_ Rcpt_ Header].[Posting Date],
dbo.[Pioneer-CO$Comment Line].[Comment],
dbo.[Pioneer-CO$Purchase Header].[Sell-to Customer No_]
HAVING
(dbo.[Pioneer-CO$Purchase Line].[Amt_ Rcd_ Not Invoiced] > '0')
ORDER BY
dbo.[Pioneer-CO$Purch_ Rcpt_ Header].[Posting Date] DESC
I would use something like this
select customer.*, lastComment.*
from account
cross apply (select top 1 * from comment where
comment.customerId=customer.customerId order by commentnumber desc) lastComment
where customer.age>30
If you need to include customers without comments use outer apply instead of cross apply
I would use following query:
OUTER APPLY
(select top 1 [Comment] from dbo.[Pioneer-CO$Comment Line] where dbo.[Pioneer-CO$Purchase Header].[Sell-to Customer No_] = dbo.[Pioneer-CO$Comment Line].[No_] order by [Posting Date] desc) Comments
Also, use Comments.[Comment] in the SELECT statement instead of dbo.[Pioneer-CO$Comment Line].[Comment]
The dbo.[Pioneer-CO$Comment Line] table should be OUTER APPLY join in the query. Also, order by comments posting date or incremental ID.
You should look at the ID or primary key, I'd imagine the newer comments have a higher ID. You could join the tables and do a Max(ID) or look for the latest timestamp if you use that on your table.
Looks like you have Customers to Comments relationship is 1 to Many(0).
How about trying something like this,
SELECT TOP 1 Customers.*, Comments.*
FROM Customers
JOIN Customers ON Customers.Id = Comments.Id
ORDER BY Comments.Id DESC
Following Added after Bib's comments
You can also try following
SELECT Customers.*, Comments.*
FROM Comments
JOIN
(SELECT MAX(Id) As CId FROM Comments GROUP BY CustomerId) AS CommentsMAX
ON CommentsMAX.CId = Comments.ID
JOIN
Customers ON Customers.Id = Comments.Id