BETWEEN condition is not working when using NOT IN - sql

SELECT *
FROM Customer
INNER JOIN Ledger Entry on [No_] = [Customer No_]
WHERE No_ NOT IN ([Posting Date] between '2013-10-01' and '2013-10-31')
the BETWEEN condition is not working.

This is not how not in works, you are comparing No_ which seems to be Id of customer with Posting Date so this should fail.
I think you wanted something like that:
SELECT *
FROM Customer c
inner join [Ledger Entry] le on c.[No_] = le.[Customer No_]
where c.[No_] not in (
select l.[Customer No_]
from [Ledger Entry] l
where l.[Posting Date] between '2013-10-01' and '2013-10-31'
)
but for such query it should be simplified to:
SELECT *
FROM
Customer c
inner join [Ledger Entry] le on c.[No_] = le.[Customer No_]
where le.[Posting Date] < '2013-10-01' or le.[Posting Date] > '2013-10-31'
without using not in and between at all

Firstly, your date should be compared to another date type column.
Secondly, according to Aaron Bertrand, you should refrain from using BETWEEN for dates, you can go through the article to know that he's right.
So intead, I'd suggest you to proceed as;
SELECT * FROM Customer
inner join LedgerEntry
on Customer.[No_] = LedgerEntry.[Customer No_]
where LedgerEntry.[Posting Date] < '2013-10-01' and LedgerEntry.[Posting Date] > '2013-10-31'

Related

How to Filter Data in SQL Without Using Group By / Having Functions

Have a situation where I'm trying to produce a query that shows the item # on a sales order and the total outstanding quantity across all orders. I can do this as follows:
SELECT
SL.[Item No_],
SUM(SL.[Outstanding Quantity])
FROM [Database$Sales Header] SH
LEFT JOIN [Database$Sales Line] SL ON SL.[Document No_] = SH.[No_]
LEFT JOIN [Database$Items] I ON I.[No_] = SL.[Item No_]
GROUP BY
SL.[Item No_],
SH.[Document Type],
I.[Product Code]
HAVING
SH.[Document Type] = '1'
AND I.[Product Code] = 'SHIRT'
ORDER BY
SL.[Item No_]
Above code gives me a simple summary of item # and qty. on all sales orders.
I'm using the HAVING clause to include only sales orders (Document Type)
and only items that are shirts (Product Code).
The issue I'm having is when I want to exclude a particular customer.
I tried adding: AND SH.[Customer No_] <> 'CUST1' to the HAVING clause but if I do that, then SQL will require me to add it in the GROUP BY clause. The result is I get duplicate rows where it was summarized before because now SQL is reporting on outstanding quantity by item # and customer # which is not what I want.
So I am not sure how to exclude that customer without putting it into GROUP BY.
Please use where clause to filter the data.
SELECT
SL.[Item No_],
SUM(SL.[Outstanding Quantity])
FROM [Database$Sales Header] SH
LEFT JOIN [Database$Sales Line] SL ON SL.[Document No_] = SH.[No_]
LEFT JOIN [Database$Items] I ON I.[No_] = SL.[Item No_]
where SH.[Customer No_] <> 'CUST1'
GROUP BY
SL.[Item No_],
SH.[Document Type],
I.[Product Code]
HAVING
SH.[Document Type] = '1'
AND I.[Product Code] = 'SHIRT'
ORDER BY
SL.[Item No_]

SQL replace int in string by text

I'm trying to do a query but in my result I have a column with the number '2' which I want to be replaced by 'factura'.
How can I do this?? I want to replace Cust.[Document Type] column
SELECT Detail.[Entry No_],
'Cliente' AS Tipo,
Cust.[Customer No_] AS Cliente,
Detail.[Posting Date] AS DATA,
Detail.[Document No_] AS Documento,
Detail.[Amount (LCY)] AS Valor,
Cust.[Document Type] AS LiqPorTipo,
Cust.[Document No_] AS LiqPorNDocumento,
'97' AS Conta,
'MR' AS Loja,
'SUPER' AS Utilizador,
'MR01' AS POS
FROM dbo.MBS_tabela_21Detailed_NAV16 AS Detail
INNER JOIN dbo.MBS_tabela_21_NAV16 AS Cust ON Detail.[Cust_ Ledger Entry No_] = Cust.[Entry No_]
INNER JOIN dbo.Integracao_Periodo_NAV16 AS Integr ON YEAR(Detail.[Posting Date]) = Integr.Ano
AND MONTH(Detail.[Posting Date]) = Integr.Mes
WHERE (Detail.[Document No_] LIKE '%REC%'
OR Detail.[Document No_] LIKE '%L%')
AND (Detail.[Entry Type] = 2)
AND (Cust.[Global Dimension 1 Code] = 'LMR')
this results in
359229 Cliente 503392154 2018-03-23 00:00:00.000 1803PAGLEITE37 -2064,62000000000000000000 2 MRVFFT1800012 97 MR SUPER MR01
and i want to have
359229 Cliente 503392154 2018-03-23 00:00:00.000 1803PAGLEITE37 -2064,62000000000000000000 fatura MRVFFT1800012 97 MR SUPER MR01
Your query is missing "Detail.[Entry Type] column". Comparing expected query result and your query result I assume you would like to use either case or create dictionary table to join it.
Best option would be to create additional table and store there all key-value translations.
So you could have
2 - factura
And join it in your query.
If not you should do like this:
SELECT Detail.[Entry No_],
'Cliente' AS Tipo,
Cust.[Customer No_] AS Cliente,
Detail.[Posting Date] AS DATA,
Detail.[Document No_] AS Documento,
Detail.[Amount (LCY)] AS Valor,
case when Cust.[Document Type] = 2 then 'factura' else '' end AS LiqPorTipo,
Cust.[Document No_] AS LiqPorNDocumento,
'97' AS Conta,
'MR' AS Loja,
'SUPER' AS Utilizador,
'MR01' AS POS
FROM dbo.MBS_tabela_21Detailed_NAV16 AS Detail
INNER JOIN dbo.MBS_tabela_21_NAV16 AS Cust ON Detail.[Cust_ Ledger Entry No_] = Cust.[Entry No_]
INNER JOIN dbo.Integracao_Periodo_NAV16 AS Integr ON YEAR(Detail.[Posting Date]) = Integr.Ano
AND MONTH(Detail.[Posting Date]) = Integr.Mes
WHERE (Detail.[Document No_] LIKE '%REC%'
OR Detail.[Document No_] LIKE '%L%')
AND (Detail.[Entry Type] = 2)
AND (Cust.[Global Dimension 1 Code] = 'LMR')
As you want to replace one column base on join result. Bellow structure may help you
UPDATE
Table_A
SET
Table_A.col1 = Table_B.col1,
Table_A.col2 = Table_B.col2
FROM
Some_Table AS Table_A
INNER JOIN Other_Table AS Table_B
ON Table_A.id = Table_B.id
WHERE
Table_A.col3 = 'cool'
Base on above structure your sql scritp is bellow.
UPDATE Detail
SET Detail.[Entry Type] = REPLACE(Detail.[Entry Type], '2', 'factura')
FROM dbo.MBS_tabela_21Detailed_NAV16 AS Detail
INNER JOIN dbo.MBS_tabela_21_NAV16 AS Cust
ON Detail.[Cust_ Ledger Entry No_] = Cust.[Entry No_]
INNER JOIN dbo.Integracao_Periodo_NAV16 AS Integr
ON YEAR(Detail.[Posting Date]) = Integr.Ano
AND MONTH(Detail.[Posting Date]) = Integr.Mes
WHERE (Detail.[Document No_] LIKE '%REC%'
OR Detail.[Document No_] LIKE '%L%')
AND (Detail.[Entry Type] = 2)
AND (Cust.[Global Dimension 1 Code] = 'LMR')

How to SQL join payments with invoices in NAV Dynamics (former Navision)

The question is about SQL fiddling in Dynamics Nav tables, especially the table [$Vendor Ledger Entry]. How to link each payment to appropriate invoices.
The aim is to get [External Document No_] and [Amount] of the invoice. One payment can be matched with many invoices (happens) or one invoice with many payments (rare case).
My desperate approach is:
;with cte as
(
select
*
,[Row_max]=max([Row]) OVER(PARTITION BY CBEN,[Document Type])
from (
select
*
,[Row]=ROW_NUMBER() OVER(PARTITION BY CBEN,[Document Type] ORDER BY [Entry No_] asc)
from (
select
*
,CBEN=case when [Closed by Entry No_]=0 then [Entry No_] else [Closed by Entry No_] end
from [CompanyName$Vendor Ledger Entry] --here put correct table name
) tb1
) tb2
)
select
a.[Entry No_] [Entry No_payment] -- letter t means transfers
,b.[Entry No_] [Entry No_invoice] -- letter p means payables
--,a.CBEN as CBEN_t
--,b.CBEN as CBEN_p
--,a.[Row_max] as Row_max_t
--,b.[Row_max] as Row_max_p
--,a.[Row] as Row_t
--,b.[Row] as Row_p
,a.[Open]
,b.[External Document No_] [External Document No_invoice]
,a.[Document No_] [Document No_payment]
,b.[Document No_] [Document No_invoice]
,b.[Document Date]
,b.[Posting Date]
,b.[Due Date]
,Amount_p=b.[Closed by Amount]
--,a.[Company]
from cte a
left join cte b
on
(
a.CBEN=b.CBEN and -- join using Closed By Entry No
(a.[Row]=b.[Row] and a.[Row_max]=b.[Row_max] or
a.Row_max=1 and not (a.[Row_max]>1 and b.[Row_max]>1) or
b.Row_max=1 and not (a.[Row_max]>1 and b.[Row_max]>1)
) and
a.[Document Type] in (0,1) and
b.[Document Type]=2
and a.[Open]=0
)
or
(
a.CBEN = b.[Entry No_] and -- or join by Closed By Entry No to EntryNo
(a.[Row]=b.[Row] and a.[Row_max]=b.[Row_max] or
a.Row_max=1 and not (a.[Row_max]>1 and b.[Row_max]>1) or
b.Row_max=1 and not (a.[Row_max]>1 and b.[Row_max]>1)
) and
a.[Document Type] in (0,1) and
b.[Document Type]=2
and a.[Open]=0
)
where
a.[Open]=0 and a.[Document Type] in (0,1) and b.[Entry No_] is not null -- show payments with matched invoices
or
a.[Open]=1 and a.[Document Type] in (0,1) and b.[Entry No_] is null -- or payments with open status
order by a.CBEN,1,2,a.[Document No_]
I am at a loss to join Invoice [Amount] and I do not know in which Dynamics NAV table it might be.
the table is
[Detailed Vendor Ledg. Entry]
with [Entry Type] = Application

How do i sum data from 2 tables left joined to 1 table?

When I comment out all lines pertaining to either the "Sales Line" or "Warehouse Entry" table the query works as expected. But when I use this query as is; it returns faulty(unrealistically high by at least 5 digits) data.
The idea is to iterate the "Item" table and to obtain the amount in stock as well as the sum of quantity sold as well as It's worth. I think there must be something wrong by the way I'm joining these tables. Both "Warehouse Entry" and "Sales Line" table have multiple entries that can be linked to I.[No_].
USE NAV2009_R2_SHOWTEX_LIVE
SELECT I.[No_]
,sum(S.[Quantity (Base)]) AS [Quantity Sold]
,min(I.[IP Total (Manual)]) * sum(WE.[Quantity]) AS [Stock Value]
,sum(WE.[Quantity]) AS [Quantity Stock]
FROM [Item] AS I
INNER JOIN [Warehouse Entry] AS WE ON WE.[Item No_] = I.[No_]
AND WE.[Location Code] = 'BU'
AND WE.[Bin Code] <> 'SHIPPING'
AND WE.[Bin Code] <> 'WORKSHOP'
AND WE.[Bin Code] <> 'OUTBOX'
AND WE.[Bin Code] <> 'CUT'
AND WE.[Bin Code] <> 'VERZEND'
INNER JOIN [Sales Line] AS S ON S.[No_] = I.[No_]
AND S.[Shipment Date] > '07/01/2015'
AND S.[Document Type] = 1
WHERE I.[No_] LIKE '140003000007'
GROUP BY I.[No_]
Sample Data
No.|Quantity Sold|Stock Value|Quantity Stock
Wrong Data
140003000007|204484537.36000000000000000000|13051602.124400| 2355884.86000000000000000000
Right Data
140003000007|61703.24000000000000000000|13623.801800|2459.17000000000000000000
SELECT sumQuantityBase as [Quantity Sold],
minIP * sumQuantityBase as [Stock Value],
sumQuantityBase as [Quantity Stock]
FROM
(SELECT MIN(I.[IP Total (Manual)] )as minIP,
No_
FROM I
WHERE [No_] like '140003000007'
GROUP BY No_) MinI INNER JOIN
(SELECT SUM([Quantity]) as sumQuantity,
[Item No_]
FROM WE
WHERE [Location Code] = 'BU'
AND [Bin Code] <> 'SHIPPING'
AND [Bin Code] <> 'WORKSHOP'
AND [Bin Code] <> 'OUTBOX'
AND [Bin Code] <> 'CUT'
AND [Bin Code] <> 'VERZEND'
GROUP BY [Item No_] ) SumWE
ON MinI.[No_] = SumWE[Item No_] INNER JOIN
(SELECT SUM([Quantity (Base)]) as sumQuantityBase,
No_
FROM S
WHERE [Shipment Date] > '07/01/2015'
AND [Shipment Date] IS NOT NULL
AND [Document Type] = 1
GROUP BY No_ ) SumS
ON SumS.[No_] = MinI.[No_]
Try this one. When you want to aggregate data using sum or min function i'd recommend you do it in a subset. that way you keep it simple

SQL Where 2 values one is empty

I'm struggling whit some SQL code for some hours now. I'm trying to combine 2 different values in one row, but if one value is not there (so no result) there will not row at all.
To be more clear: I have a Location whit 2 different values, those are coming from two queries. That is working fine, but sometime the second query give no results (can happen, is not bad), but than also the first value is not shown.
Declare #Start datetime,
#Ende datetime;
SET #Start = '01.04.2015';
SET #Ende = '30.04.2015';
SELECT t1.[Location Code], CAST(t1.Umsatz as DECIMAL(18,2))as Umsatz , CAST(t2.Ersatznachweis as DECIMAL(18,2)) as Ersatznachweis
FROM (
SELECT [Location Code], SUM(WareBrutto) AS Umsatz
FROM (SELECT DISTINCT [Location Code], [Document No_] , WareBrutto from [Item Ledger Entry]
WHERE [Location Code] > '0000' and [Location Code] < '0040' and [Document Date] >= #Start and [Document Date] <= #Ende) t
GROUP BY [Location Code]) as t1,
(select [Location Code], sum([Quantity]*Bruttopreis) as Ersatznachweis from [Item Ledger Entry]
where [Location Code] > '0000' and [Location Code] < '0040' and [Item No_] not IN ('00009000','00009900','00009906') and Gutschrift = '1' and [Document Date] >= #Start and [Document Date] <= #Ende
Group By [Location Code]) as t2
where t1.[Location Code] = t2.[Location Code]
order by t1.[Location Code]
It is the second query that sometimes does not return a value.
(select [Location Code], sum([Quantity]*Bruttopreis) as Ersatznachweis from [Item Ledger Entry]
where [Location Code] > '0000' and [Location Code] < '0040' and [Item No_] not IN ('00009000','00009900','00009906') and Gutschrift = '1' and [Document Date] >= #Start and [Document Date] <= #Ende
Group By [Location Code]) as t2
But that when it comes to the end and there is no result of t2.[Location code] the result of t1 is also not shown.
where t1.[Location Code] = t2.[Location Code]
I want that t2 gets a value of zero when there is no result. I tried isnull and the coalesec option but I was not able to get a decent result. It is just not there or I get error messages.
Thank in advanced...
Using Toad for SQl on a 2012 MSSQL server.
The problem is that the comma join and where clause you're using makes the join an inner join (Thanks to the comment from Ed B for adding details to this). In an inner join, only matching records are shown. Since there are no records in t2, nothing is matching in t1, and no records are returned. You're looking for a LEFT join, which will join any matching records from the 2nd table to the returned records from the 1st table. If nothing is in the 2nd table, you still get all of the original records from the 1st table.
I've updated your code so it uses a LEFT join, does the join in an ON statement instead of a where, and uses COALESCE to show 0 instead of NULL for records that don't match.
The following should get what you're looking for:
Declare #Start datetime,
#Ende datetime;
SET #Start = '01.04.2015';
SET #Ende = '30.04.2015';
SELECT t1.[Location Code], CAST(t1.Umsatz as DECIMAL(18,2))as Umsatz , CAST(COALESCE(t2.Ersatznachweis, 0) as DECIMAL(18,2)) as Ersatznachweis
FROM (
SELECT [Location Code], SUM(WareBrutto) AS Umsatz
FROM (SELECT DISTINCT [Location Code], [Document No_] , WareBrutto from [Item Ledger Entry]
WHERE [Location Code] > '0000' and [Location Code] < '0040' and [Document Date] >= #Start and [Document Date] <= #Ende) t
GROUP BY [Location Code]) as t1
LEFT JOIN (select [Location Code], sum([Quantity]*Bruttopreis) as Ersatznachweis from [Item Ledger Entry]
where [Location Code] > '0000' and [Location Code] < '0040' and [Item No_] not IN ('00009000','00009900','00009906') and Gutschrift = '1' and [Document Date] >= #Start and [Document Date] <= #Ende
Group By [Location Code]) as t2 ON t1.[Location Code] = t2.[Location Code]
order by t1.[Location Code]
You should use a better syntax in your statements. Use a join instead of select from 2 comma seperated tables.
Then you'll see that you'll need a left join.
SELECT ... AS t1
LEFT JOIN
(SELECT ...) AS t2 ON t1.[Location Code] = t2.[Location Code]
...