My sql query is
select I.[Old Product Code],
I.[Trade Name],
I.[Short Name],
SIL.[BOM Item No_] ,
CASE when SIL.[Dimension Group Code] = 'IOL'
then I.[Group Description]
else I.[Short Name] END as GD,
CASE when SIL.[BOM Item No_] <> ''
then 'Kit' end
from [Sales Invoice Header] SIH, [Sales Invoice Line] SIL, [Item] I
where I.No_ = SIL.No_
and SIL.[Document No_] = 'PEXP1213-153'
and SIH.No_ = SIL.[Document No_]
group by I.[Old Product Code], I.[Trade Name], I.[Short Name],
SIL.[Dimension Group Code], I.[Group Description], SIL.[BOM Item No_]
And my result is
In this out of 21 rows i am having 17 rows as kit. I need to group this kit and to display in Old Product Code as Kit in one row instead of 17 rows.
Looking at what you are trying to do you might be able to use something like this to return the data:
;with data as
(
select I.[Old Product Code],
I.[Trade Name],
I.[Short Name],
SIL.[BOM Item No_] ,
CASE when SIL.[Dimension Group Code] = 'IOL'
then I.[Group Description]
else I.[Short Name] END as GD,
CASE when SIL.[BOM Item No_] <> ''
then 'Kit' end CombinedKit
from SalesInvoiceHeader SIH
inner join SalesInvoiceLine SIL
on SIH.No_ = SIL.[Document No_]
inner join Item I
on I.No_ = SIL.No_
where SIL.[Document No_] = 'PEXP1213-153'
),
d2 as
(
select [Old Product Code],
[Trade Name],
[Short Name],
[BOM Item No_],
GD,
CombinedKit,
row_number()
over(partition by CombinedKit order by [Old Product Code]) rn
from data
)
select
case when combinedkit = 'kit'
then 'Kit' else [Old Product Code] end [Old Product Code],
[Trade Name],
[Short Name],
[BOM Item No_],
GD
--, CombinedKit
from d2
where (CombinedKit = 'Kit' and rn = 1)
or (CombinedKit is null)
See SQL Fiddle with Demo
Edit, if you want to order this in a specific way you can use Order By with a CASE statement:
;with data as
(
select I.[Old Product Code],
I.[Trade Name],
I.[Short Name],
SIL.[BOM Item No_] ,
CASE when SIL.[Dimension Group Code] = 'IOL'
then I.[Group Description]
else I.[Short Name] END as GD,
CASE when SIL.[BOM Item No_] <> ''
then 'Kit' end CombinedKit
from SalesInvoiceHeader SIH
inner join SalesInvoiceLine SIL
on SIH.No_ = SIL.[Document No_]
inner join Item I
on I.No_ = SIL.No_
where SIL.[Document No_] = 'PEXP1213-153'
),
d2 as
(
select [Old Product Code],
[Trade Name],
[Short Name],
[BOM Item No_],
GD,
CombinedKit,
row_number()
over(partition by CombinedKit order by [Old Product Code]) rn
from data
)
select
case when combinedkit = 'kit'
then 'Kit' else [Old Product Code] end [Old Product Code],
[Trade Name],
[Short Name],
[BOM Item No_],
GD
--, CombinedKit
from d2
where (CombinedKit = 'Kit' and rn = 1)
or (CombinedKit is null)
order by
case when combinedkit = 'kit' then 0 else 1 end, [Old Product Code]
See SQL Fiddle with Demo
Related
I have an access database that I am converting to SQL Server and there is a report that has the follow:
SELECT tblInventoryUnit.[ORG-IU],
tblInventoryUnit.[Parent ORG Name],
tblVehicle.[Asset Tag Number],
tblVehicle.[Vehicle Unit Type],
tblVehicle.[Historical Unit Number],
tblVehicle.[License Plate Number],
tblVehicle.[Model Year],
tblVehicle.Make,
tblVehicle.Model,
tblVehicle.[Acquisition Date],
tblVehicle.[Vehicle Cost],
tblVehicle.[Insurance Account],
tblVehicle.[Insurance Sub-Account],
tblVehicle.[Project Code],
tblFSOTeams.[Fund Accountant Team],
tblVehicle.[Vehicle Status]
FROM tblSPSTeams
RIGHT JOIN(tblFSOTeams
INNER JOIN(tblInventoryUnit
INNER JOIN tblVehicle
ON tblInventoryUnit.[ORG-IU] = tblVehicle.[ORG-IU])
ON tblFSOTeams.[Org Number] = tblInventoryUnit.[Parent ORG])
ON tblSPSTeams.[Account Number] = tblVehicle.[Insurance Account]
WHERE (
((tblVehicle.[Vehicle Unit Type]) <> 'TA')
AND ((tblVehicle.[Acquisition Date]) < '7/15/2020')
AND
(
(tblVehicle.[Vehicle Status]) = 'Pending - Motor Pool'
OR (tblVehicle.[Vehicle Status]) = 'Active - In Use'
OR (tblVehicle.[Vehicle Status]) = 'Active - Unlocated'
OR (tblVehicle.[Vehicle Status]) = 'Active - Surplused'
)
AND ((tblSPSTeams.[SPS Team Number]) IS NULL)
)
OR
(
((tblVehicle.[Vehicle Unit Type]) <> 'TA')
AND ((tblVehicle.[Acquisition Date]) < '7/15/2020')
AND ((tblVehicle.[Vehicle Status]) = 'Inactive')
AND ((tblSPSTeams.[SPS Team Number]) IS NULL)
AND ((tblVehicle.[Disposal Date]) > '7/1/2020')
);
I have figured out from looking at the diagram that this equals:
SELECT tblInventoryUnit.[ORG-IU],
tblInventoryUnit.[Parent ORG Name],
tblVehicle.[Asset Tag Number],
tblVehicle.[Vehicle Unit Type],
tblVehicle.[Historical Unit Number],
tblVehicle.[License Plate Number],
tblVehicle.[Model Year],
tblVehicle.Make,
tblVehicle.Model,
tblVehicle.[Acquisition Date],
tblVehicle.[Vehicle Cost],
tblVehicle.[Insurance Account],
tblVehicle.[Insurance Sub-Account],
tblVehicle.[Project Code],
tblFSOTeams.[Fund Accountant Team],
tblVehicle.[Vehicle Status]
FROM dbo.tblVehicle
LEFT JOIN dbo.tblSPSTeams
ON dbo.tblVehicle.[Insurance Account] = dbo.tblSPSTeams.[Account Number]
INNER JOIN dbo.tblInventoryUnit
ON tblInventoryUnit.[ORG-IU] = tblVehicle.[ORG-IU]
INNER JOIN dbo.tblFSOTeams
ON tblFSOTeams.[Org Number] = dbo.tblInventoryUnit.[Parent ORG]
WHERE (
((tblVehicle.[Vehicle Unit Type]) <> 'TA')
AND ((tblVehicle.[Acquisition Date]) < '7/15/2020')
AND
(
(tblVehicle.[Vehicle Status]) = 'Pending - Motor Pool'
OR (tblVehicle.[Vehicle Status]) = 'Active - In Use'
OR (tblVehicle.[Vehicle Status]) = 'Active - Unlocated'
OR (tblVehicle.[Vehicle Status]) = 'Active - Surplused'
)
AND ((tblSPSTeams.[SPS Team Number]) IS NULL)
)
OR
(
((tblVehicle.[Vehicle Unit Type]) <> 'TA')
AND ((tblVehicle.[Acquisition Date]) < '7/15/2020')
AND ((tblVehicle.[Vehicle Status]) = 'Inactive')
AND ((tblSPSTeams.[SPS Team Number]) IS NULL)
AND ((tblVehicle.[Disposal Date]) > '7/1/2020')
);
Can someone explain how the first query works? I don't get the syntax. In particular, this part:
FROM tblSPSTeams
RIGHT JOIN(tblFSOTeams
INNER JOIN(tblInventoryUnit
INNER JOIN tblVehicle
ON tblInventoryUnit.[ORG-IU] = tblVehicle.[ORG-IU])
ON tblFSOTeams.[Org Number] = tblInventoryUnit.[Parent ORG])
ON tblSPSTeams.[Account Number] = tblVehicle.[Insurance Account]
It looks like two subqueries but there is no select statement in the inner tables. I tried to add a select statement like a "normal" subquery but it balked at the idea. How exactly does this work? Is there a special syntax that I am not getting?
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')
SELECT ap.ID, ap.[Adjustment Name], ap.[Adjustment Name Description], ap.[2nd Item Number], [ap].Description, ap.[Unit of Measure], ap.[Effective Date], ap.[Expired Date], MAX( ap.[Factor Value Numeric] ) , ap.[Prc Cls], ap.[Prc Cls Description], ap.[Address Number], ap.[Sales Detail Value 01], ap.[Currency Code], c.[Customer Pricing Rule], c.[Alpha Name]
FROM [Adv Price Query Export] ap
INNER JOIN ( SELECT [Adjustment Name], [2nd Item Number], MAX([Effective Date]), [Factor Value Numeric], [Sales Detail Value 01]
FROM [Adv Price Query Export] ) s ON ((s.[Adjustment Name] = ap.[Adjustment Name]) AND (s.[Effective Date] = ap.[Effective Date]) AND (s.[Sales Detail Value 01] = ap.[Sales Detail Value 01]))
INNER JOIN Customer c ON (ap.[Adjustment Name] = c.[Adjustment Schedule])
WHERE ( ap.[2nd Item Number] = "18500" OR ap.[2nd Item Number] = "185047" OR ap.[2nd Item Number] = "18550" OR ap.[2nd Item Number] = "26004" OR ap.[2nd Item Number] = "55010" )
GROUP BY ap.[Sales Detail Value 01]
Not sure where the error is but you can re-write your query like below
SELECT ap.ID,
ap.[Adjustment Name],
ap.[Adjustment Name Description],
ap.[2nd Item Number],
[ap].Description,
ap.[Unit of Measure],
ap.[Effective Date],
ap.[Expired Date],
MAX( ap.[Factor Value Numeric] ) ,
ap.[Prc Cls],
ap.[Prc Cls Description],
ap.[Address Number],
ap.[Sales Detail Value 01],
ap.[Currency Code],
c.[Customer Pricing Rule],
c.[Alpha Name]
FROM [Adv Price Query Export] ap
INNER JOIN ( SELECT [Adjustment Name],
[2nd Item Number],
MAX([Effective Date]),
[Factor Value Numeric],
[Sales Detail Value 01]
FROM [Adv Price Query Export] ) s
ON s.[Adjustment Name] = ap.[Adjustment Name]
AND s.[Effective Date] = ap.[Effective Date]
AND s.[Sales Detail Value 01] = ap.[Sales Detail Value 01]
INNER JOIN Customer c ON ap.[Adjustment Name] = c.[Adjustment Schedule]
WHERE ap.[2nd Item Number] IN ("18500", "185047", "18550", "26004", "55010" )
GROUP BY ap.[Sales Detail Value 01]
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
I want to pass the value of 1 of my columns in my SELECT statements in a Variable.
Here's my sample code:
DECLARE #TotalExpense DECIMAL(18,2)
SELECT a.[Posting Date] AS [Check Date],
a.[Document No_] AS [Check Number],
a.[Vendor No_],
(
SELECT SUM(CASE WHEN GLEntry.[VAT Amount] <> 0 THEN CAST(GLEntry.Amount AS DECIMAL(18,2)) ELSE 0 END) FROM [BLI$Detailed Vendor Ledg_ Entry] DtldVendLedger
LEFT JOIN [BLI$G_L Entry] GLEntry
ON GLEntry.[Document No_] = (SELECT VendLedger.[Document No_] FROM [BLI$Vendor Ledger Entry] VendLedger
WHERE VendLedger.[Entry No_] = DtldVendLedger.[Vendor Ledger Entry No_])
WHERE DtldVendLedger.[Entry Type] = 2 AND DtldVendLedger.[Initial Document Type] = 2 AND DtldVendLedger.[Document No_] = a.[Document No_]
AND GLEntry.[Source Code] = 'PURCHASES' AND GLEntry.[G_L Account No_] NOT IN ('2003','1402','1403','1401')
) AS [Vatable],
(
SELECT SUM(CASE WHEN GLEntry.[VAT Amount] <> 0 THEN CAST(GLEntry.Amount * 0.12 AS DECIMAL(18,2)) ELSE 0 END) FROM [BLI$Detailed Vendor Ledg_ Entry] DtldVendLedger
LEFT JOIN [BLI$G_L Entry] GLEntry
ON GLEntry.[Document No_] = (SELECT VendLedger.[Document No_] FROM [BLI$Vendor Ledger Entry] VendLedger
WHERE VendLedger.[Entry No_] = DtldVendLedger.[Vendor Ledger Entry No_])
WHERE DtldVendLedger.[Entry Type] = 2 AND DtldVendLedger.[Initial Document Type] = 2 AND DtldVendLedger.[Document No_] = a.[Document No_]
AND GLEntry.[Source Code] = 'PURCHASES' AND GLEntry.[G_L Account No_] NOT IN ('2003','1402','1403','1401')
) AS [Input Tax],
(
SELECT SUM(CASE WHEN GLEntry.[VAT Amount] = 0 THEN CAST(GLEntry.Amount AS DECIMAL(18,2)) ELSE 0 END) FROM [BLI$Detailed Vendor Ledg_ Entry] DtldVendLedger
LEFT JOIN [BLI$G_L Entry] GLEntry
ON GLEntry.[Document No_] = (SELECT VendLedger.[Document No_] FROM [BLI$Vendor Ledger Entry] VendLedger
WHERE VendLedger.[Entry No_] = DtldVendLedger.[Vendor Ledger Entry No_])
WHERE DtldVendLedger.[Entry Type] = 2 AND DtldVendLedger.[Initial Document Type] = 2 AND DtldVendLedger.[Document No_] = a.[Document No_]
AND GLEntry.[Source Code] = 'PURCHASES' AND GLEntry.[G_L Account No_] NOT IN ('2003','1402','1403','1401')
) AS [Non-Vat]
I want to Sum the Vatable, Input Tax, and Nonvat then pass the value into a variable then that variable will be used in my SELECT statements.
I tried to rearrange your query a bit. In your query the part with the DtldVendLedger query inside the join condition should not be valid. If you got that to run I have no idea how.
Because of the way I think you're summing I don't think it matters whether you used outer joins or inner joins. The rows with null GLEntry count as zeroes anyway.
DECLARE #vatable DECIMAL(18, 2);
DECLARE #inputtax DECIMAL(18, 2);
DECLARE #nonvat DECIMAL(18, 2);
SELECT
#vatable = SUM(
CASE
WHEN GLEntry.[VAT Amount] <> 0
THEN CAST(GLEntry.Amount AS DECIMAL(18,2)) ELSE 0 END
),
#nonvat = SUM(
CASE
WHEN GLEntry.[VAT Amount] = 0
THEN CAST(GLEntry.Amount AS DECIMAL(18,2)) ELSE 0 END
)
FROM
A as a /* I'm assuming there was a FROM referencing a table "a" */
[BLI$Detailed Vendor Ledg_ Entry] DtldVendLedger
INNER JOIN
ON DtldVendLedger.[Document No_] = a.[Document No_]
LEFT OUTER JOIN [BLI$Vendor Ledger Entry] VendLedger
ON VendLedger.[Entry No_] = DtldVendLedger.[Vendor Ledger Entry No_]
LEFT OUTER JOIN [BLI$G_L Entry] GLEntry
ON GLEntry.[Document No_] = VendLedger.[Document No_]
WHERE
a.??? = ???
AND DtldVendLedger.[Entry Type] = 2
AND DtldVendLedger.[Initial Document Type] = 2
AND GLEntry.[Source Code] = 'PURCHASES'
AND GLEntry.[G_L Account No_] NOT IN ('2003','1402','1403','1401');
SET #inputtax = 0.12 * #vatable;