Use where clause in temporary table - mysql

I am trying to use where clause in temporary table. Actually i used it but results aren't true. trying to find products between 2 dates but when i use where clause it gets no data.
CREATE TABLE #TEMPCOZGU
(
ROW INT,
TEZGAH VARCHAR(50),
COZGU VARCHAR(50),
PERSONEL VARCHAR(50),
DATE DATETIME,
FIRE INT,
FIRE_METRE NUMERIC(25,6)
)
INSERT INTO #TEMPCOZGU
select row_number() over(order by TEZGAH) AS ROW, TEZGAH, COZGU, PERSONEL, TARIH, FIRE, FIRE_METRE
from cozgu_fırelerı
where tezgah = 'M01' and cozgu = 'SAĞ ALT BAĞLANTI'
SELECT T1.TEZGAH, T1.COZGU, T1.PERSONEL,T1.FIRE, T1.FIRE_METRE, t1.DATE, T2.DATE AS PREVIOUSDATE, ISNULL(DATEDIFF(DAY, T2.DATE, T1.DATE), 0) AS GUNFARKI , SUM(MKARE) AS TOPLAMMKARE
FROM #TEMPCOZGU as t1
left outer join #TEMPCOZGU as t2 on t1.row-1 = t2.row
left outer join HALI_TEZGAH AS TE ON T1.TEZGAH = TE.TEZGAH_NO
LEFT OUTER JOIN HALI_GUNLUK_URETIM AS U ON U.TEZGAH = TE.ID
--WHERE U.TARIH BETWEEN T1.TARIH AND T2.TARIH
GROUP BY T1.TEZGAH, T1.COZGU, T1.PERSONEL, T1.DATE,T1.FIRE, T1.FIRE_METRE, T2.DATE
drop table #TEMPCOZGU`

If the datetime values always have the time set to "00:00:00", try
SELECT T1.TEZGAH, T1.COZGU, T1.PERSONEL,T1.FIRE, T1.FIRE_METRE, t1.DATE, T2.DATE AS PREVIOUSDATE, ISNULL(DATEDIFF(DAY, T2.DATE, T1.DATE), 0) AS GUNFARKI , SUM(MKARE) AS TOPLAMMKARE
FROM #TEMPCOZGU as t1
left outer join #TEMPCOZGU as t2 on t1.row-1 = t2.row
left outer join HALI_TEZGAH AS TE ON T1.TEZGAH = TE.TEZGAH_NO
LEFT OUTER JOIN HALI_GUNLUK_URETIM AS U ON U.TEZGAH = TE.ID
WHERE U.TARIH >= T1.TARIH AND U.TARIH < DateADD (T2.TARIH, INTERVAL 1 DAY)
GROUP BY T1.TEZGAH, T1.COZGU, T1.PERSONEL, T1.DATE,T1.FIRE, T1.FIRE_METRE, T2.DATE
If that's not the case, then your between should have worked in the first place.

Related

Mysql LEFT JOIN with most recent record?

I have this query:
SELECT A.ISIN, A.CUSIP, A.Currency, A.StatedFinalMaturityDate,
A.FirstPayDate, A.PaymentDelay, A.trancheName, A.DealTicker,
B.TrancheCoupon, B.OneMonthCoupon, B.SettleDate, B.Factor,
B.paymentDate
from table1 A
left JOIN table2 B on (A.DealTicker = B.DealTicker AND A.trancheName=B.trancheName)
where A.ISIN IN ('XS2004372095','XS1679333432','XS0333340361',
'XS0333337813','XS0333324241','XS0333323862',
'XS0333323516','XS0333323193','XS0333316908',
'XS0333313988','USWFMW0N9Z05','USWFHZ5XIY05',
'USWFHVA6TK04','USWFHTXSQJ03');
Here table1 have one record correspond to each ISIN but the table2 can have multiple rows.
table2 has settleDate column which show latest row. So I want to select only latest row from table2 only. Since table2 need two JOINING column I m little confused here.
PS: I cannot use mysql 8 features like row_number() as mysql server version is 5.7. And my table contains more than 150millions records. I tried a approaches but didn't work because of huge data.
You are using a very old MySQL version, so you cannot use windows functions but must access the same table twice. You can use NOT EXISTS or MAX to get the last rows. Here is an example with MAX:
SELECT
a.isin, a.cusip, a.currency, a.statedfinalmaturitydate, a.firstpaydate,
a.paymentdelay, a.tranchename, a.dealticker, b.tranchecoupon,
b.onemonthcoupon, b.settledate, b.factor, b.paymentdate
FROM table1 a
LEFT JOIN
(
SELECT *
FROM table2
WHERE (dealticker, tranchename, settledate) IN
(
SELECT dealticker, tranchename, max(settledate)
FROM table2
GROUP BY dealticker, tranchename
)
) b ON b.dealticker = a.dealticker AND b.tranchename = a.tranchename
where a.isin IN ('XS2004372095','XS1679333432','XS0333340361','XS0333337813',
'XS0333324241','XS0333323862','XS0333323516','XS0333323193',
'XS0333316908','XS0333313988','USWFMW0N9Z05','USWFHZ5XIY05',
'USWFHVA6TK04','USWFHTXSQJ03');
You can use window functions:
SELECT A.ISIN, A.CUSIP, A.Currency, A.StatedFinalMaturityDate, A.FirstPayDate, A.PaymentDelay, A.trancheName, A.DealTicker,
B.TrancheCoupon, B.OneMonthCoupon, B.SettleDate, B.Factor, B.paymentDate
FROM table1 A LEFT JOIN
(SELECT b.*,
ROW_NUMBER() OVER (PARTITION BY DealTicker, trancheName ORDER BY settleDate DESC) as seqnum
FROM table2 B
) B
ON A.DealTicker = B.DealTicker AND
A.trancheName = B.trancheName AND
B.seqnum = 1
WHERE A.ISIN IN ('XS2004372095','XS1679333432','XS0333340361','XS0333337813','XS0333324241','XS0333323862','XS0333323516','XS0333323193','XS0333316908','XS0333313988','USWFMW0N9Z05','USWFHZ5XIY05','USWFHVA6TK04','USWFHTXSQJ03');
In older versions of MySQL, you can use:
SELECT A.ISIN, A.CUSIP, A.Currency, A.StatedFinalMaturityDate, A.FirstPayDate, A.PaymentDelay, A.trancheName, A.DealTicker,
B.TrancheCoupon, B.OneMonthCoupon, B.SettleDate, B.Factor, B.paymentDate
FROM table1 A LEFT JOIN
table2 B
ON A.DealTicker = B.DealTicker AND
A.trancheName = B.trancheName AND
B.settleDate = (SELECT MAX(b2.settleDate)
FROM table2 b2
WHERE b2.DealTicker = B.DealTicker AND
b2.trancheName = B.trancheName
)
WHERE A.ISIN IN ('XS2004372095','XS1679333432','XS0333340361','XS0333337813','XS0333324241','XS0333323862','XS0333323516','XS0333323193','XS0333316908','XS0333313988','USWFMW0N9Z05','USWFHZ5XIY05','USWFHVA6TK04','USWFHTXSQJ03');

MySQL statement not including Null values [duplicate]

This question already has answers here:
Left Outer Join doesn't return all rows from my left table?
(3 answers)
Closed 2 years ago.
SELECT DISTINCT
CAST(`t1`.`ImportedOn` AS DATE) AS `DispatchDate`,
`t1`.`Order` AS `order`,
`t1`.`Operation` AS `QbOP`,
`t1`.`UserOpStatus` AS `OpsAway`,
`t1`.`UnloadingPoint` AS `Location`,
`t1`.`WorkCenter` AS `QbWC`,
`t1`.`LatestStartDate` AS `QbStartDay`,
`t1`.`LatestStartTime` AS `QbStartTime`,
`t2`.`Operation` AS `RcOP`,
`t2`.`WorkCenter` AS `RcWC`,
`t2`.`LatestStartDate` AS `lateststartdate`,
`t2`.`LatestStartTime` AS `lateststarttime`,
`wc`.`CellName` AS `CellName`,
IF((`wooc`.`ConfirmationDate` IS NULL),
'Open',
IF((`t1`.`UserOpStatus` = 'run'),
'Running',
'Done')) AS `Status`
FROM
(((`workorderoperationschedule` `t1`
LEFT JOIN `workorderoperationschedule` `t2` ON (((`t1`.`Order` = `t2`.`Order`)
AND (`t2`.`Operation` > `t1`.`Operation`)
AND (`t2`.`Operation` < (`t1`.`Operation` + 11)))))
LEFT JOIN `workcenters` `wc` ON ((`wc`.`WorkCenter` = `t1`.`WorkCenter`)))
LEFT JOIN `workorderoperationconfirmations` `wooc` ON (((`wooc`.`Order` = `t1`.`Order`)
AND (`wooc`.`Operation` = `t1`.`Operation`))))
WHERE
((`t1`.`LatestStartDate` <= CAST(`t1`.`ImportedOn` AS DATE))
AND (`t1`.`ImportedOn` = (SELECT
MAX(`t1`.`ImportedOn`)
FROM
`workorderoperationschedule` `t1`))
AND (`t2`.`ImportedOn` = (SELECT
MAX(`t1`.`ImportedOn`)
FROM
`workorderoperationschedule` `t1`)))
ORDER BY `Status` DESC , `t1`.`WorkCenter` , `t2`.`LatestStartDate` , `t2`.`LatestStartTime`
My challenge is that sometimes t2 will not have a value, which is expected, however, i think MySQL is not returning those rows when t2 has not match. I thought a left join would return all values from t1 and only the values from t2 that match but that is not happening
If you need a left join then you can't use a colunm of a left joined table in a where condition so try move the t2 condition for max value in the related ON clause
SELECT DISTINCT
CAST(`t1`.`ImportedOn` AS DATE) AS `DispatchDate`,
`t1`.`Order` AS `order`,
`t1`.`Operation` AS `QbOP`,
`t1`.`UserOpStatus` AS `OpsAway`,
`t1`.`UnloadingPoint` AS `Location`,
`t1`.`WorkCenter` AS `QbWC`,
`t1`.`LatestStartDate` AS `QbStartDay`,
`t1`.`LatestStartTime` AS `QbStartTime`,
`t2`.`Operation` AS `RcOP`,
`t2`.`WorkCenter` AS `RcWC`,
`t2`.`LatestStartDate` AS `lateststartdate`,
`t2`.`LatestStartTime` AS `lateststarttime`,
`wc`.`CellName` AS `CellName`,
IF((`wooc`.`ConfirmationDate` IS NULL),
'Open',
IF((`t1`.`UserOpStatus` = 'run'),
'Running',
'Done')) AS `Status`
FROM
(((`workorderoperationschedule` `t1`
LEFT JOIN `workorderoperationschedule` `t2` ON (((`t1`.`Order` = `t2`.`Order`)
AND (`t2`.`Operation` > `t1`.`Operation`)
AND (`t2`.`Operation` < (`t1`.`Operation` + 11)))))
AND (`t2`.`ImportedOn` = (SELECT
MAX(`t1`.`ImportedOn`)
FROM
`workorderoperationschedule` `t1`))
LEFT JOIN `workcenters` `wc` ON ((`wc`.`WorkCenter` = `t1`.`WorkCenter`)))
LEFT JOIN `workorderoperationconfirmations` `wooc` ON (((`wooc`.`Order` = `t1`.`Order`)
AND (`wooc`.`Operation` = `t1`.`Operation`))))
WHERE
((`t1`.`LatestStartDate` <= CAST(`t1`.`ImportedOn` AS DATE))
AND (`t1`.`ImportedOn` = (SELECT
MAX(`t1`.`ImportedOn`)
FROM
`workorderoperationschedule` `t1`))
AND (`t2`.`ImportedOn` = (SELECT
MAX(`t1`.`ImportedOn`)
FROM
`workorderoperationschedule` `t1`)))
ORDER BY `Status` DESC , `t1`.`WorkCenter` , `t2`.`LatestStartDate` , `t2`.`LatestStartTime`
WHERE
((`t1`.`LatestStartDate` <= CAST(`t1`.`ImportedOn` AS DATE))
AND (`t1`.`ImportedOn` = (SELECT
MAX(`t1`.`ImportedOn`)
FROM
`workorderoperationschedule` `t1`))
)
The predicate:
`t2`.`ImportedOn` = (SELECT MAX(`t1`.`ImportedOn`)
FROM `workorderoperationschedule` `t1`)
in the WHERE clause is silently converting your LEFT JOIN into an INNER JOIN.
To make the left join work you need to move this predicate to the ON clause when joinining t2.

How to join with having in mysql?

All, I face a problem with join mysql. I want to get a result with count a unique amount of staff_id field using GROUP BY. If I run this query I got result as I want at one step.
SELECT id,staff_id,note,warning_date FROM tbl_warning GROUP BY staff_id HAVING (count(staff_id) > 0);
The next I want to join two more tables to get field such as tbl_employment.com_id as comid, tbl_staff.name, tbl_staff.gender but the result are duplicate.
`SELECT` `tbl_warning`.`id`, `tbl_warning`.`staff_id`, `tbl_warning`.`note`, `tbl_warning`.`warning_date`,`tbl_employment`.`com_id` as `comid`, `tbl_staff`.`name`, `tbl_staff`.`gender` FROM `tbl_warning`
JOIN `tbl_employment` ON `tbl_employment`.`staff_id` = `tbl_warning`.`staff_id`
JOIN `tbl_staff` ON `tbl_staff`.`id` = `tbl_warning`.`staff_id`
HAVING (SELECT `staff_id` FROM `tbl_warning` GROUP BY `staff_id` HAVING (count(staff_id) > 1));
I want unique result same first screenshot.
Thank you!
You should join to a subquery which finds the matching staff by count:
SELECT
t1.id,
t1.staff_id,
t1.note,
t1.warning_date,
t2.com_id as `comid`,
t3.name,
t3.gender
FROM tbl_warning t1
INNER JOIN tbl_employment t2
ON t2.staff_id = t1.staff_id
INNER JOIN tbl_staff t3
ON t3.id = t1.staff_id
INNER JOIN
(
SELECT staff_id
FROM tbl_warning
GROUP BY staff_id
HAVING COUNT(*) > 1
) t
ON t.staff_id = t2.staff_id;

MySQL derived table with join

In the following query I'm having a problem when it comes to returning the right value for count2.
What I need is to get the number of rows from table2 which could easily be done by using a derived table t:
SELECT name,
(SELECT COUNT(*) FROM `table1`) AS count1,
(SELECT COUNT(*) FROM (
SELECT COUNT(*) FROM `table2` t2) WHERE t2.user = prf.user)
) t AS count2,
(SELECT SUM(a) FROM `table3`) AS count3
FROM `profiles` prf
WHERE 1=1
AND prf.user = 1
The problem is that the WHERE t2.user = prf.user statement fails as the prf table is outside the subquery's scope.
How can I achieve the above?
EDIT: I'm adding the actual query in case it's helpful for getting a better grasp:
SELECT PRF.BranchID, PRF.user_id, CONCAT_WS(" ",PRF.lastname,PRF.firstname) Synergatis,
( SELECT COUNT(*) FROM Actions A JOIN Requests R ON R.RequestID=A.RequestID WHERE A.ActionStatus = 302 AND A.UserOwner = PRF.user_id AND A.ActionDate BETWEEN '2015-06-01' AND '2015-06-10' ) AS energeies,
( SELECT COUNT(DISTINCT RPP.RequestID) FROM VW_Xartofylakio_Synergati VV JOIN Requests_Prop RPP ON RPP.PropertyID = VV.PropertyID JOIN Requests R ON R.RequestID = RPP.RequestID WHERE VV.CurrUsr = PRF.user_id AND R.ModifyTime BETWEEN '2015-06-01' AND '2015-06-10' ) AS zitiseis_eidikes,
( SELECT COUNT(DISTINCT(CustomerID)) FROM Demo_Orders_M WHERE DemoOrderStatus=253 AND USER=PRF.user_id AND DemoOrderDate BETWEEN '2015-06-01' AND '2015-06-10' ) AS endiaferomenoi,
( SELECT COUNT(*) AS cnt FROM Demo_Orders_M DOM JOIN Actions A ON DOM.DemoOrderID = A.DemoOrderID WHERE DOM.User = PRF.user_id AND DOM.DemoOrderStatus = 253 AND A.ActionDate BETWEEN '2015-06-01 14:56:19' AND '2015-06-30 14:56:19' GROUP BY DOM.CustomerID, DOM.User HAVING COUNT(*) > 1 ) AS anakykl_endiaf,
( SELECT COUNT(*) FROM Demo_Orders_M DOM WHERE DOM.`User`=PRF.user_id AND DemoOrderStatus = 253 AND DOM.DemoOrderDate BETWEEN '2015-06-01' AND '2015-06-10' ) AS epideixeis,
( SELECT COUNT(DISTINCT(DOD.PropertyID)) AS PropertyID FROM Demo_Orders_M DOM JOIN Demo_Orders_D DOD ON DOM.DemoOrderID = DOD.DemoOrderID JOIN Actions A ON DOD.DemoOrderID = A.DemoOrderID WHERE DOM.DemoOrderStatus = 253 AND DOM.User = PRF.user_id AND A.ActionDate BETWEEN '2015-06-01' AND '2015-06-10' ) AS monadika_akinita
FROM tbl_profiles PRF
WHERE 1=1
AND PRF.user_id IN (
SELECT a.user_id FROM tbl_profiles a WHERE a.user_id IN ('248','1159','486','183')
OR a.GroupID IN (SELECT b.GroupID FROM L_Groups b WHERE b.ManagerID IN ('248','1159','486','183'))
)
ORDER BY PRF.user_id
The subquery I'm referring to is the one that returns the result as anakykl_endiaf.
I suspect it is not because of prf table, it is because of t2 table... There are no restrictions to use outer alias in inner subqueries because there are such a thing like correlated subquery. Your problem is that you have the opposite case here: you are referring inner alias in outer query.
(SELECT COUNT(*)
FROM (SELECT COUNT(*) FROM `table2` t2) WHERE t2.user = prf.user)
Why are you selecting count twice here? You can change to this:
(SELECT COUNT(*)
FROM (SELECT COUNT(*) FROM `table2` t2 WHERE t2.user = prf.user))
or this:
(SELECT COUNT(*)
FROM `table2` t2 WHERE t2.user = prf.user)
A suggestion to try.
You have sub queries in the SELECT, and in this case they must each only return a single row. For some reason (which we can't really tell without test data) one of these is returning more than 1 row, hence failing.
As an interim step, change the query to join against the sub queries, which should make it more obvious when there are duplicates (and may also be quite a bit more efficient, depending on the data).
Something like this (not tested so probably a few typos):-
SELECT PRF.BranchID,
PRF.user_id,
CONCAT_WS(" ",PRF.lastname,PRF.firstname) Synergatis,
ar.energeies,
vrr.zitiseis_eidikes,
m.endiaferomenoi,
ae.anakykl_endiaf,
d.epideixeis,
ddd.monadika_akinita
FROM tbl_profiles PRF
LEFT OUTER JOIN
(
SELECT A.UserOwner AS DomUser, COUNT(*) AS energeies
FROM Actions A
JOIN Requests R ON R.RequestID=A.RequestID
WHERE A.ActionStatus = 302
AND A.ActionDate BETWEEN '2015-06-01' AND '2015-06-10'
GROUP BY A.UserOwner
) ar
ON ar.DomUser = PRF.user_id
LEFT OUTER JOIN
(
SELECT VV.CurrUsr AS DomUser, COUNT(DISTINCT RPP.RequestID) AS zitiseis_eidikes
FROM VW_Xartofylakio_Synergati VV
JOIN Requests_Prop RPP ON RPP.PropertyID = VV.PropertyID
JOIN Requests R ON R.RequestID = RPP.RequestID
WHERE R.ModifyTime BETWEEN '2015-06-01' AND '2015-06-10'
GROUP BY VV.DomUser
) vrr
ON vrr.DomUser = PRF.user_id
LEFT OUTER JOIN
(
SELECT `USER` AS DomUser, COUNT(DISTINCT(CustomerID)) AS endiaferomenoi
FROM Demo_Orders_M
WHERE DemoOrderStatus=253
AND DemoOrderDate BETWEEN '2015-06-01' AND '2015-06-10'
GROUP BY DomUser
) m
ON PRF.user_id = m.DomUser
LEFT OUTER JOIN
(
SELECT DOM.CustomerID, DOM.`User` AS DomUser, COUNT(*) AS anakykl_endiaf
FROM Demo_Orders_M DOM
JOIN Actions A ON DOM.DemoOrderID = A.DemoOrderID
WHERE DOM.DemoOrderStatus = 253
AND A.ActionDate BETWEEN '2015-06-01 14:56:19' AND '2015-06-30 14:56:19'
GROUP BY DOM.CustomerID, DOM.DomUser
HAVING COUNT(*) > 1
) ae
ON PRF.user_id = ae.DomUser
LEFT OUTER JOIN
(
SELECT DOM.`User` AS DomUser, COUNT(*) AS epideixeis
FROM Demo_Orders_M DOM
WHERE DemoOrderStatus = 253
AND DOM.DemoOrderDate BETWEEN '2015-06-01' AND '2015-06-10'
GROUP BY DOM.DomUser
) d
EDIT
If you just want a count of the number of customerID fields for a user in the anakykl_endiaf field then change it to doing a count of distinct customerIDs. Ie, for the above query I have done change it to:-
LEFT OUTER JOIN
(
SELECT DOM.`User` AS DomUser, COUNT(DISTINCT DOM.CustomerID) AS anakykl_endiaf
FROM Demo_Orders_M DOM
JOIN Actions A ON DOM.DemoOrderID = A.DemoOrderID
WHERE DOM.DemoOrderStatus = 253
AND A.ActionDate BETWEEN '2015-06-01 14:56:19' AND '2015-06-30 14:56:19'
GROUP BY DOM.DomUser
HAVING COUNT(*) > 1
) ae

More than one Case in same query are generating more than one row

My problem is actually I have multiple tables and I'm using two case statements to generate one column for ARV1 and one for ICA1, but I need the results are generated in the same row. When I usecase, generate the two columns but the values are displayed in two rows. What am I missing?
the thing is, i have an invoice the table OINV and have the table INV5 that is the table with the Holding Taxes, i need to put on the same row the invoice with all the Holding Taxes in different columns that are applying on it, thanks
this is the example tables
CREATE TABLE Invoice
(
Id INT, InvoiceNumber VARCHAR(10), Total INT
)
INSERT INTO Invoice
VALUES
(1,'200000',100),
(2,'200001',200),
(3,'200002',500),
(4,'200003',700),
(5,'200004',200),
(6,'200005',100),
(7,'200006',300)
CREATE TABLE HoldingTaxes
(
Id INT, HoldingTaxCode VARCHAR(10),HoldedAmount INT)
)
INSERT INTO HoldingTaxes
VALUES
(1,'ARV1',20),
(1,'ARV2',30),
(1,'ARV3',35),
(2,'ICA1',20),
(2,'ARV1',10),
(1,'ICA3',50)
I want a query that returns something like this:
InvoiceNumber Total ARV1 ARV2 ARV3 ICA1 ICA2 ICA3
200000 100 20 30 35 null null 50
This is what i am trying to do with my real tables
SELECT T0.DocNum [No. Factura],
CASE
WHEN t5.WTCode ='ARV1' and (t5.U_Ret_ML <>0 AND t5.U_Ret_ML is not null)
THEN 'Perro1'
else NULL
end AS ARV1
,
CASE
WHEN t5.WTCode ='ICA1' and (t5.U_Ret_ML <>0 AND t5.U_Ret_ML is not null)
THEN 'Perro2'
else NULL
end AS ICA1
FROM OINV T0
INNER JOIN INV1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN OSLP T4 ON T0.SlpCode = T4.SlpCode
INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode
INNER JOIN OITW T3 ON T2.ItemCode = T3.ItemCode
INNER JOIN INV5 T5 ON T5.AbsEntry = T0.DocEntry
WHERE T1.WhsCode = T3.WhsCode`enter code here`
GROUP BY T0.DocNum,T0.DocDate,T0.DocTotal, T0.GrosProfit, T4.SlpName,T5.WTCODE,t5.U_Ret_ML
Alternative way :
SELECT inv.InvoiceNumber,inv.Total,[ARV1],[ARV2],[ARV3],[ICA1],[ICA2],[ICA3]
FROM INVOICE inv
JOIN(
SELECT id,[ARV1],[ARV2],[ARV3],[ICA1],[ICA2],[ICA3]
FROM
(SELECT * FROM HoldingTaxes ) t1
PIVOT(SUM(HoldedAmount) for HoldingTaxCode in
([ARV1],[ARV2],[ARV3],[ICA1],[ICA2],[ICA3])) t2
) ht
ON inv.id =ht.id
sql fiddle :http://sqlfiddle.com/#!3/ea3a4/10
I would use PIVOT to solve this - as demonstrated in the SQL Fiddle:
SELECT EmpName
,CASE WHEN ARV1 > 0 THEN 'PERRO1' ELSE NULL END
,CASE WHEN ARV2 > 0 THEN 'PERRO2' ELSE NULL END
,CASE WHEN ICA1 > 0 THEN 'PERRO3' ELSE NULL END
FROM (SELECT t0.EmpName, t1.Name, t1.Value
FROM Table0 t0 INNER JOIN Table1 t1 ON t0.Id = t1.Id ) as src
PIVOT (
MAX(src.Value)
FOR src.Name IN ([ARV1],[ARV2],[ICA1])) as p
http://sqlfiddle.com/#!3/a6ff0/2
If your having issues and willing to share your structure, I can put this into a a closer match to what you are using on SQL Fiddle.
Edit:
Based on the update you gave, here is the fiddle I created with the pivot.
http://sqlfiddle.com/#!3/47511/4
SELECT * FROM
(SELECT InvoiceNumber = Invoice.InvoiceNumber
,Total = Invoice.Total
,HoldingTaxCode = HoldingTaxes.HoldingTaxCode
,HoldedAmount = HoldingTaxes.HoldedAmount
FROM Invoice
LEFT JOIN HoldingTaxes
ON Invoice.Id = HoldingTaxes.Id) PivotSource
PIVOT
(
SUM(HoldedAmount) FOR HoldingTaxCode IN(ARV1, ARV2, ARV3, ICA1, ICA2, ICA3)
) PivotData
ORDER BY InvoiceNumber
The two CASE expressions employ the same logic. Only the value in t5.WTCode is different. Since that column is unlikely to have the value ARV1 and ICA1 at the same time you'll always get a NULL in at least one of the computed columns in any row.
You are putting different case statements for 2 different values. Therefore for each row one of them would be valid and other one null, which is what you are getting.
This is how i resolved my issue, thanks to everyone for the help
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(t5.WTCode)
FROM INV5 T5
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT Factura, Fecha, SN, TotalFacturaSinImpuesto, Total$Descuento, Total$Impuesto, Total$Retenciones, Total$Factura, CostoTotal$Factura, Margen$Factura, Costo$PromedioInventario, Margen$Inventario, NombreVendedor, ' + #cols + ' from
(
select T0.DocNum [Factura], T0.DocDate [Fecha], T0.CardName [SN],SUM(T1.LineTotal) [TotalFacturaSinImpuesto], T0.DiscSum [Total$Descuento], T0.VatSum [Total$Impuesto],(T0.WTSum*-1) [Total$Retenciones],t5.WTCode [CodigoRetencion],t5.U_Ret_ML [CantidadRetenida],T0.DocTotal [Total$Factura],SUM(T1.GrossBuyPr*T1.Quantity) [CostoTotal$Factura], T0.GrosProfit [Margen$Factura],SUM(T1.Quantity*T3.AvgPrice) [Costo$PromedioInventario],(SUM(T1.LineTotal*T1.Quantity))-(SUM(T1.Quantity*T3.AvgPrice)) [Margen$Inventario], T4.SlpName [NombreVendedor]
FROM OINV T0
INNER JOIN INV1 T1 ON T0.DocEntry = T1.DocEntry
INNER JOIN OSLP T4 ON T0.SlpCode = T4.SlpCode
INNER JOIN OITM T2 ON T1.ItemCode = T2.ItemCode
INNER JOIN OITW T3 ON T2.ItemCode = T3.ItemCode
INNER JOIN INV5 T5 ON T5.AbsEntry = T0.DocEntry
WHERE T1.WhsCode = T3.WhsCode
GROUP BY T0.DocNum,T0.DocDate, T0.CardName,T0.BaseAmnt, T0.DiscSum, T0.VatSum, T0.WTSum,T0.DocTotal, T0.GrosProfit, T4.SlpName,T5.WTCODE,T5.U_RET_ML
) x
pivot
(
sum(CantidadRetenida)
for CodigoRetencion in (' + #cols + ')
) p '
execute(#query)