How can i remove an group result sql - sql

I have a SQL query but it gives me more results that I want. For example when I run the query I will get 20 results from 2 products. Each product has a group by and the group by of the g.linkedline must be ignored and not shown in the results.
This is the query that I have
I tried to make a select over my select. I also tried a TOP 1 but it gives me 1 result.
SELECT i.itemcode,
g.warehouse,
Sum(g.aantal) AS Voorraad,
Max(CASE
WHEN g.transtype = 'N' THEN g.sysmodified
ELSE NULL
END) AS LastDate
FROM dbo.gbkmut AS g
INNER JOIN dbo.items AS i
ON g.artcode = i.itemcode
AND g.reknr = i.glaccountdistribution
AND ( g.transtype = 'N'
OR ( g.transtype = 'B'
AND g.transsubtype = 'B'
AND g.freefield1 NOT IN ( 'B', 'Q', 'W', 'K' )
AND g.blockitem = '0'
AND g.allocationtype = 'F' )
OR ( g.transtype = 'B'
AND g.transsubtype = 'B'
AND g.freefield1 = 'V'
AND g.allocationtype = 'B' ) )
WHERE g.transtype = 'N'
AND ( i.itemcode = 'TESTARTIKEL'
OR i.itemcode = 'IQ7-60-2-INT' )
GROUP BY i.itemcode,
g.warehouse,
g.linkedline

I'd try it like this, you can use the window function row_number to force a ranking. If you are interested in only 1 thing per unique item code or where house, the nyou substitute the thing of interest in the Partition by clause and then specify what you want to order on in the order by clause. For example in the query below the item of interest is the ItemCode and we are ordering on the warehouse and aantal desc (which I'm assuming you want to see items with more aantal than less, but you can remove desc if you that suits your needs.
select * from
(
SELECT row_number()over(partition by i.Itemcode order by g.warehouse, g.aantal desc) as rowno, i.ItemCode, g.warehouse, SUM(g.aantal) AS Voorraad, MAX(CASE WHEN g.transtype = 'N' THEN g.sysmodified ELSE NULL END) AS LastDate
FROM dbo.gbkmut AS g INNER JOIN dbo.Items AS i
ON g.artcode = i.ItemCode AND g.reknr = i.GLAccountDistribution AND (
g.transtype = 'N' OR
(g.transtype = 'B' AND
g.transsubtype = 'B' AND
g.freefield1 NOT IN ('B', 'Q', 'W', 'K') AND
g.BlockItem = '0' AND
g.AllocationType = 'F') OR ( g.transtype = 'B' AND g.transsubtype = 'B' AND g.freefield1 = 'V' AND g.AllocationType = 'B'))
WHERE g.transtype = 'N' AND (i.ItemCode = 'TESTARTIKEL' OR i.ItemCode = 'IQ7-60-2-INT') GROUP BY i.ItemCode, g.warehouse, g.LinkedLine
) x where rowno=1;

SELECT i.ItemCode, g.warehouse, SUM(g.aantal) AS Voorraad,
MAX(CASE WHEN g.transtype = 'N' THEN g.sysmodified ELSE NULL END) AS LastDate
FROM dbo.gbkmut AS g INNER JOIN dbo.Items AS i
ON g.artcode = i.ItemCode AND g.reknr = i.GLAccountDistribution AND (
g.transtype = 'N' OR
(g.transtype = 'B' AND
g.transsubtype = 'B' AND
g.freefield1 NOT IN ('B', 'Q', 'W', 'K') AND
g.BlockItem = '0' AND
g.AllocationType = 'F') OR ( g.transtype = 'B' AND g.transsubtype = 'B' AND g.freefield1 = 'V' AND g.AllocationType = 'B'))
WHERE g.transtype = 'N' AND i.ItemCode = 'IQ7-60-2-INT' GROUP BY i.ItemCode, g.warehouse, g.LinkedLine
This returns results first Voorraad 0 and with the script of DwightReynoldson it returns 1080

I found the problem. thank you all!
There was a desc to the Voorraad thats is why the result wasn't correct.
This is the Code
select * from
(
SELECT
i.ItemCode,
g.warehouse,
SUM(g.aantal) AS Voorraad,
MAX(CASE
WHEN g.transtype = 'N' THEN g.sysmodified
ELSE NULL
END) AS LastDate,
row_number()
over
(partition by
i.Itemcode
order by
g.warehouse
) as rowno
FROM dbo.gbkmut AS g
INNER JOIN dbo.Items AS i
ON g.artcode = i.ItemCode
AND g.reknr = i.GLAccountDistribution
AND ( g.transtype = 'N'
OR ( g.transtype = 'B'
AND g.transsubtype = 'B'
AND g.freefield1 NOT IN ( 'B', 'Q', 'W', 'K' )
AND g.blockitem = '0'
AND g.allocationtype = 'F' )
OR ( g.transtype = 'B'
AND g.transsubtype = 'B'
AND g.freefield1 = 'V'
AND g.allocationtype = 'B' ) )
WHERE g.transtype = 'N'
AND ( i.itemcode = 'TESTARTIKEL'
OR i.itemcode = 'IQ7-60-2-INT' )
GROUP BY i.itemcode,
g.warehouse,
g.linkedline
) x where rowno=1 ;

You can use:
select *****Here the columns that you want to use****** from (****Your query****) anyName
In your case:
select *****Here the columns that you want to use****** from (
SELECT i.ItemCode, g.warehouse, SUM(g.aantal) AS Voorraad, MAX(CASE WHEN g.transtype = 'N' THEN g.sysmodified ELSE NULL END) AS LastDate
FROM dbo.gbkmut AS g INNER JOIN dbo.Items AS i
ON g.artcode = i.ItemCode AND g.reknr = i.GLAccountDistribution AND (
g.transtype = 'N' OR
(g.transtype = 'B' AND
g.transsubtype = 'B' AND
g.freefield1 NOT IN ('B', 'Q', 'W', 'K') AND
g.BlockItem = '0' AND
g.AllocationType = 'F') OR ( g.transtype = 'B' AND g.transsubtype = 'B' AND g.freefield1 = 'V' AND g.AllocationType = 'B'))
WHERE g.transtype = 'N' AND (i.ItemCode = 'TESTARTIKEL' OR i.ItemCode = 'IQ7-60-2-INT') GROUP BY i.ItemCode, g.warehouse, g.LinkedLine
) Name

Related

reuse of subqueries with different WHERE clause

I have a query which I looks schematically like this
WITH sub_base AS (
SELECT type,
CASE WHEN a < 10 THEN 'GOOD'
WHEN a BETWEEN 10 AND 100 THEN 'OK'
ELSE 'BAD'
END AS a_q,
...
CASE WHEN z < 5 THEN 'GOOD'
WHEN z BETWEEN 5 AND 50 THEN 'OK'
ELSE 'BAD'
END AS z_q
FROM tbl
),
SELECT sub_one AS (
SELECT 'one' AS type,
COUNT(CASE WHEN a_q = 'GOOD' THEN 1) a_good,
COUNT(CASE WHEN a_q = 'OK' THEN 1) a_ok,
COUNT(CASE WHEN a_q = 'BAD' THEN 1) a_bad,
...
COUNT(CASE WHEN z_q = 'GOOD' THEN 1) z_good,
COUNT(CASE WHEN z_q = 'OK' THEN 1) z_ok,
COUNT(CASE WHEN z_q = 'BAD' THEN 1) z_bad,
FROM sub_base
WHERE type = 'one'
),
SELECT sub_two AS (
SELECT 'two' AS type,
COUNT(CASE WHEN a_q = 'GOOD' THEN 1) a_good,
COUNT(CASE WHEN a_q = 'OK' THEN 1) a_ok,
COUNT(CASE WHEN a_q = 'BAD' THEN 1) a_bad,
...
COUNT(CASE WHEN z_q = 'GOOD' THEN 1) z_good,
COUNT(CASE WHEN z_q = 'OK' THEN 1) z_ok,
COUNT(CASE WHEN z_q = 'BAD' THEN 1) z_bad,
FROM sub_base
WHERE type = 'two'
),
SELECT sub_all AS (
SELECT 'all' AS type,
COUNT(CASE WHEN a_q = 'GOOD' THEN 1) a_good,
COUNT(CASE WHEN a_q = 'OK' THEN 1) a_ok,
COUNT(CASE WHEN a_q = 'BAD' THEN 1) a_bad,
...
COUNT(CASE WHEN z_q = 'GOOD' THEN 1) z_good,
COUNT(CASE WHEN z_q = 'OK' THEN 1) z_ok,
COUNT(CASE WHEN z_q = 'BAD' THEN 1) z_bad,
FROM sub_base
)
SELECT * FROM sub_one
UNION
SELECT * FROM sub_two
UNION
SELECT * FROM sub_all
I want to reuse the subqueries in sub_one, sub_two, sub_all because they are almost identical with the exception of type in SELECT and the WHERE condition.
How can I avoid copy-pasting these subqueries?
Use GROUP BY:
SELECT type,
COUNT(CASE WHEN a_q = 'GOOD' THEN 1) as a_good,
COUNT(CASE WHEN a_q = 'OK' THEN 1) as a_ok,
COUNT(CASE WHEN a_q = 'BAD' THEN 1) as a_bad,
...
COUNT(CASE WHEN z_q = 'GOOD' THEN 1) as z_good,
COUNT(CASE WHEN z_q = 'OK' THEN 1) as z_ok,
COUNT(CASE WHEN z_q = 'BAD' THEN 1) as z_bad,
FROM sub_base
WHERE type IN ('one', 'two', 'three') -- may not be needed
GROUP BY type;
In Postgres, I would further simplify this. You could use FILTER or summing binary values:
SELECT type,
SUM( (a_q = 'GOOD')::int ) as a_good,
SUM( (a_q = 'OK')::int ) as a_ok,
SUM( (a_q = 'BAD')::int ) as a_bad,
...
SUM( (z_q = 'GOOD')::int ) as z_good,
SUM( (z_q = 'OK')::int ) as z_ok,
SUM( (z_q = 'BAD')::int ) as z_bad,
FROM sub_base
WHERE type IN ('one', 'two', 'three') -- may not be needed
GROUP BY type;
I would also dispense with the CTE and just put the logic in the outer query directly, but that is more a matter of style.
EDIT:
You can use another CTE:
WITH . . . ,
t as (
SELECT type,
SUM( (a_q = 'GOOD')::int ) as a_good,
SUM( (a_q = 'OK')::int ) as a_ok,
SUM( (a_q = 'BAD')::int ) as a_bad,
...
SUM( (z_q = 'GOOD')::int ) as z_good,
SUM( (z_q = 'OK')::int ) as z_ok,
SUM( (z_q = 'BAD')::int ) as z_bad,
FROM sub_base
WHERE type IN ('one', 'two', 'three') -- may not be needed
GROUP BY type
)
SELECT t.*
FROM t
UNION ALL
SELECT 'Total', SUM(a_good), SUM(a_ok), SUM(a_bad), . . .
FROM t;
Why not using a second CTE?
WITH sub_base AS (
...
),
second_cte AS (
SELECT
type,
COUNT(CASE WHEN a_q = 'GOOD' THEN 1) a_good,
COUNT(CASE WHEN a_q = 'OK' THEN 1) a_ok,
COUNT(CASE WHEN a_q = 'BAD' THEN 1) a_bad,
...
COUNT(CASE WHEN z_q = 'GOOD' THEN 1) z_good,
COUNT(CASE WHEN z_q = 'OK' THEN 1) z_ok,
COUNT(CASE WHEN z_q = 'BAD' THEN 1) z_bad
FROM sub_base
)
SELECT
*
FROM second_cte
WHERE type = 'one'
UNION
SELECT
*
FROM second_cte
WHERE type = 'two'
UNION
SELECT
*
FROM second_cte
WHERE type = 'all'
You don't even need two CTE's in your case, because you don't reuse the first one. So you can put it into a subquery:
WITH cte AS (
SELECT
type,
COUNT(CASE WHEN a_q = 'GOOD' THEN 1) a_good,
COUNT(CASE WHEN a_q = 'OK' THEN 1) a_ok,
COUNT(CASE WHEN a_q = 'BAD' THEN 1) a_bad,
...
COUNT(CASE WHEN z_q = 'GOOD' THEN 1) z_good,
COUNT(CASE WHEN z_q = 'OK' THEN 1) z_ok,
COUNT(CASE WHEN z_q = 'BAD' THEN 1) z_bad
FROM (
SELECT
<your sub_base query here>
) s
)
SELECT
*
FROM second_cte
WHERE type = 'one'
UNION
SELECT
*
FROM second_cte
WHERE type = 'two'
UNION
SELECT
*
FROM second_cte
WHERE type = 'all'

Missing parenthesis for case statement

While running the below SQL I'm getting an error:
Missing parenthesis
SELECT DISTINCT
RPH.transport_mode, PCP.air_export_ind, PCP.air_import_ind
FROM
RATE_PROFILE_HEADER RPH, PARTNER_CHARGE_PROFILE PCP
WHERE
PCP.charge_code = RPH.Charge_code
AND PCP.charge_calculation_method = 'R'
AND RPH.RP_RECORD_ID = PCP.CHARGE_RATEPROF_RECORD_ID
AND CASE '&psTransport_mode'
WHEN 'A'
THEN (DECODE(RPH.transport_mode, 'ALL', 'A', RPH.transport_mode) = 'A') AND (PCP.air_export_ind = 'Y' or PCP.air_import_ind = 'Y')
WHEN 'M'
THEN (DECODE(RPH.transport_mode, 'ALL', 'M', RPH.transport_mode) = 'M') AND (PCP.air_export_ind = 'Y' or PCP.air_import_ind = 'Y')
ELSE NULL
END
I want to pass multiple conditions in THEN for WHERE clause.
Should I have to use an IF statement?
How about not using a CASE statement at all. It seems like you just need a nested conditional:
Select
distinct
RPH.transport_mode,
PCP.air_export_ind,
PCP.air_import_ind
from
RATE_PROFILE_HEADER RPH,
PARTNER_CHARGE_PROFILE PCP
where
PCP.charge_code = RPH.Charge_code
AND PCP.charge_calculation_method = 'R'
AND RPH.RP_RECORD_ID = PCP.CHARGE_RATEPROF_RECORD_ID
AND
(
'&psTransport_mode' = 'A' AND ( Decode(RPH.transport_mode,'ALL','A',RPH.transport_mode) = 'A') AND (PCP.air_export_ind = 'Y' or PCP.air_import_ind = 'Y')
OR
'&psTransport_mode' = 'M' AND ( Decode(RPH.transport_mode,'ALL','M',RPH.transport_mode) = 'M') AND (PCP.air_export_ind = 'Y' or PCP.air_import_ind = 'Y')
)

ERROR! - Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause

I'm getting this error: Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause.
I've looked around but I can not find anything to help me in my case.
I am using SQL Server 2012
SELECT DISTINCT
CommodityCode.CommodityCode AS ComCode,
Facility.FacilityAcctNum,
Vessel.VesselType,
Facility.FacilityNm,
Case
When Commodities.ShippedReceivedId = 'R' And Commodities.ForeignDomesticId = 'F' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End AS RecF,
Case
When Commodities.ShippedReceivedId = 'R' And Commodities.ForeignDomesticId = 'D' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End AS RecD,
Case
When Commodities.ShippedReceivedId = 'S' And Commodities.ForeignDomesticId = 'D' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End AS Shipped,
Case
When Commodities.ShippedReceivedId = 'S' And Commodities.ForeignDomesticId = 'F' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End AS ShippedF,
Commodities.Destination,
Commodities.Origin,
Commodities.Specific,
CommodityCode.Descr,
Facility.FacilityID,
TransactionCharge.ArrivalDt,
TransactionCharge.DepartDt,
TransactionCharge.DtDocked,
TransactionCharge.DtSailed
FROM Vessel
INNER JOIN Commodities
INNER JOIN CommodityCode ON Commodities.CommodityCode = CommodityCode.CommodityCode
INNER JOIN TransactionCharge ON Commodities.TransactionID = TransactionCharge.TransactionID ON Vessel.VesselID = TransactionCharge.VesselId
INNER JOIN Facility ON TransactionCharge.FacilityID = Facility.FacilityID
INNER JOIN Unit ON Commodities.Unit = Unit.Unit
INNER JOIN TransactionFee ON TransactionCharge.TransactionID = TransactionFee.TransactionID
GROUP BY
CommodityCode.CommodityCode,
Facility.FacilityAcctNum,
Vessel.VesselType,
Facility.FacilityNm,
Commodities.Destination,
Commodities.Origin,
Commodities.Specific,
CommodityCode.Descr,
Facility.FacilityID,
Case
When Commodities.ShippedReceivedId = 'R' And Commodities.ForeignDomesticId = 'F' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End,
Case
When Commodities.ShippedReceivedId = 'R' And Commodities.ForeignDomesticId = 'D' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End,
Case
When Commodities.ShippedReceivedId = 'S' And Commodities.ForeignDomesticId = 'D' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End,
Case
When Commodities.ShippedReceivedId = 'S' And Commodities.ForeignDomesticId = 'F' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End,
TransactionCharge.ArrivalDt,
TransactionCharge.DepartDt,
TransactionCharge.DtDocked,
TransactionCharge.DtSailed
HAVING (Vessel.VesselType='V' Or Vessel.VesselType='O')
You have subqueries in your case statement in your GROUP BY. For example, looking at the first part of the case statement:
When Commodities.ShippedReceivedId = 'R' And Commodities.ForeignDomesticId = 'F' Then
Case When Commodities.Amount Is Null Or Commodities.Unit Is Null Then Null
Else
Round (Commodities.Amount/Case When Commodities.Unit = 'B' Then (Select BushelFactor From CommodityCode
Where CommodityCode.CommodityCode = Commodities.CommodityCode)
Else (Select ShortTonFactor From Unit
Where Unit.Unit = Commodities.Unit) End,2
)
End
Else 0
End,
There are two there to start with, beginning with Select BushelFactor... and Select ShortTonFactor..., so you will have to remove them.
I had a quick go at reformatting your query and removing/ commenting some of the issues with it:
SELECT --DISTINCT - do you really want DISTINCT?
cc.CommodityCode AS ComCode,
f.FacilityAcctNum,
v.VesselType,
f.FacilityNm,
CASE
WHEN Commodities.ShippedReceivedId = 'R' AND Commodities.ForeignDomesticId = 'F' THEN
CASE
WHEN Commodities.Amount IS NULL OR Commodities.Unit IS NULL THEN NULL
ELSE ROUND(Commodities.Amount /
CASE
WHEN Commodities.Unit = 'B' THEN cc.BushelFactor
ELSE u.ShortTonFactor
END, 2)
END
ELSE 0
END AS RecF,
CASE
WHEN Commodities.ShippedReceivedId = 'R' AND Commodities.ForeignDomesticId = 'D' THEN
CASE
WHEN Commodities.Amount IS NULL OR Commodities.Unit IS NULL THEN NULL
ELSE
ROUND(Commodities.Amount /
CASE
WHEN Commodities.Unit = 'B' THEN cc.BushelFactor
ELSE u.ShortTonFactor END, 2)
END
ELSE 0
END AS RecD,
CASE
WHEN Commodities.ShippedReceivedId = 'S' AND Commodities.ForeignDomesticId = 'D' THEN
CASE
WHEN Commodities.Amount IS NULL OR Commodities.Unit IS NULL THEN NULL
ELSE
ROUND(Commodities.Amount /
CASE
WHEN Commodities.Unit = 'B' THEN cc.BushelFactor
ELSE u.ShortTonFactor
END, 2)
END
ELSE 0
END AS Shipped,
CASE
WHEN Commodities.ShippedReceivedId = 'S' AND Commodities.ForeignDomesticId = 'F' THEN
CASE
WHEN Commodities.Amount IS NULL OR Commodities.Unit IS NULL THEN NULL
ELSE
ROUND(Commodities.Amount/
CASE
WHEN Commodities.Unit = 'B' THEN cc.BushelFactor
ELSE u.ShortTonFactor
END, 2)
END
ELSE 0
END AS ShippedF,
c.Destination,
c.Origin,
c.Specific,
cc.Descr,
f.FacilityID,
tc.ArrivalDt,
tc.DepartDt,
tc.DtDocked,
tc.DtSailed
FROM
Vessel v
INNER JOIN Commodities c ON --some_condtion, OR is this a cross join?
INNER JOIN CommodityCode cc ON c.CommodityCode = cc.CommodityCode
INNER JOIN TransactionCharge tc ON c.TransactionID = tc.TransactionID AND v.VesselID = tc.VesselId
INNER JOIN Facility f ON tc.FacilityID = f.FacilityID
INNER JOIN Unit u ON c.Unit = u.Unit
INNER JOIN TransactionFee td ON tc.TransactionID = tf.TransactionID
WHERE
v.VesselType IN ('V', 'O');
I don't expect this to produce the answers you want, but it might make it easier to spot what is wrong with your original query now that the logic is somewhat simplified?

SQL Server 2008 r2 CASE Expression not evaluating correctly

I've got the following SQL statement that is not determining when a field has a value of 'Y' when it should. Here is the SQL...
SELECT A.BUSINESS_UNIT
, A.WO_ID
, A.WO_TASK_ID
, A.ENS_TSK_CRT_VAL
, (CASE WHEN A.ENS_TSK_CRT_V01 = 'Y' THEN B.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V01
, (CASE WHEN A.ENS_TSK_CRT_V02 = 'Y' THEN C.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V02
, (CASE WHEN A.ENS_TSK_CRT_V03 = 'Y' THEN D.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V03
, (CASE WHEN A.ENS_TSK_CRT_V04 = 'Y' THEN E.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V04
, (CASE WHEN A.ENS_TSK_CRT_V05 = 'Y' THEN F.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V05
, (CASE WHEN A.ENS_TSK_CRT_V06 = 'Y' THEN G.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V06
, (CASE WHEN A.ENS_TSK_CRT_V07 = 'Y' THEN H.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V07
, (CASE WHEN A.ENS_TSK_CRT_V08 = 'Y' THEN I.DESCR ELSE ' ' END) AS ENS_TSK_CRT_V08
FROM PS_ENS_WM_TSKCR_VW A LEFT OUTER JOIN (
SELECT A.BUSINESS_UNIT
, A.WO_TASK_ID
, C.DESCR
, A.WO_ID
, C.ENS_TSK_CRT_CD
FROM PS_ENS_WM_TSKCR_VW A
, PS_ENS_WM_TSK_CRT C
WHERE A.ENS_TSK_CRT_V01 = 'Y'
AND C.SETID = 'SHARE'
AND C.ENS_TSK_CRT_CD = '01' ) B ON B.BUSINESS_UNIT = A.BUSINESS_UNIT
AND B.WO_ID = A.WO_ID
AND B.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN (
SELECT A.BUSINESS_UNIT
, A.WO_TASK_ID
, C.DESCR
, A.WO_ID
, C.ENS_TSK_CRT_CD
FROM PS_ENS_WM_TSKCR_VW A
, PS_ENS_WM_TSK_CRT C
WHERE A.ENS_TSK_CRT_V01 = 'Y'
AND C.SETID = 'SHARE'
AND C.ENS_TSK_CRT_CD = '02' ) C ON C.BUSINESS_UNIT = A.BUSINESS_UNIT
AND C.WO_ID = A.WO_ID
AND C.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN (
SELECT A.BUSINESS_UNIT
, A.WO_TASK_ID
, C.DESCR
, A.WO_ID
, C.ENS_TSK_CRT_CD
FROM PS_ENS_WM_TSKCR_VW A
, PS_ENS_WM_TSK_CRT C
WHERE A.ENS_TSK_CRT_V01 = 'Y'
AND C.SETID = 'SHARE'
AND C.ENS_TSK_CRT_CD = '03' ) D ON D.BUSINESS_UNIT = A.BUSINESS_UNIT
AND D.WO_ID = A.WO_ID
AND D.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN (
SELECT A.BUSINESS_UNIT
, A.WO_TASK_ID
, C.DESCR
, A.WO_ID
, C.ENS_TSK_CRT_CD
FROM PS_ENS_WM_TSKCR_VW A
, PS_ENS_WM_TSK_CRT C
WHERE A.ENS_TSK_CRT_V01 = 'Y'
AND C.SETID = 'SHARE'
AND C.ENS_TSK_CRT_CD = '04' ) E ON E.BUSINESS_UNIT = A.BUSINESS_UNIT
AND E.WO_ID = A.WO_ID
AND E.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN (
SELECT A.BUSINESS_UNIT
, A.WO_TASK_ID
, C.DESCR
, A.WO_ID
, C.ENS_TSK_CRT_CD
FROM PS_ENS_WM_TSKCR_VW A
, PS_ENS_WM_TSK_CRT C
WHERE A.ENS_TSK_CRT_V01 = 'Y'
AND C.SETID = 'SHARE'
AND C.ENS_TSK_CRT_CD = '05' ) F ON F.BUSINESS_UNIT = A.BUSINESS_UNIT
AND F.WO_ID = A.WO_ID
AND F.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN (
SELECT A.BUSINESS_UNIT
, A.WO_TASK_ID
, C.DESCR
, A.WO_ID
, C.ENS_TSK_CRT_CD
FROM PS_ENS_WM_TSKCR_VW A
, PS_ENS_WM_TSK_CRT C
WHERE A.ENS_TSK_CRT_V01 = 'Y'
AND C.SETID = 'SHARE'
AND C.ENS_TSK_CRT_CD = '06' ) G ON G.BUSINESS_UNIT = A.BUSINESS_UNIT
AND G.WO_ID = A.WO_ID
AND G.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN (
SELECT A.BUSINESS_UNIT
, A.WO_TASK_ID
, C.DESCR
, A.WO_ID
, C.ENS_TSK_CRT_CD
FROM PS_ENS_WM_TSKCR_VW A
, PS_ENS_WM_TSK_CRT C
WHERE A.ENS_TSK_CRT_V01 = 'Y'
AND C.SETID = 'SHARE'
AND C.ENS_TSK_CRT_CD = '07' ) H ON H.BUSINESS_UNIT = A.BUSINESS_UNIT
AND H.WO_ID = A.WO_ID
AND H.WO_TASK_ID = A.WO_TASK_ID LEFT OUTER JOIN (
SELECT A.BUSINESS_UNIT
, A.WO_TASK_ID
, C.DESCR
, A.WO_ID
, C.ENS_TSK_CRT_CD
FROM PS_ENS_WM_TSKCR_VW A
, PS_ENS_WM_TSK_CRT C
WHERE A.ENS_TSK_CRT_V01 = 'Y'
AND C.SETID = 'SHARE'
AND C.ENS_TSK_CRT_CD = '08' ) I ON I.BUSINESS_UNIT = A.BUSINESS_UNIT
AND I.WO_ID = A.WO_ID
AND I.WO_TASK_ID = A.WO_TASK_ID
WHERE ( A.ENS_TSK_CRT_VAL <> 0
AND A.WO_ID = '0000002151'
AND A.BUSINESS_UNIT = 'R3851' )
The case statements sometimes pick up the 'Y' and behave as expected, sometimes they don't. The fields being examined for 'Y' values are CHAR fields of one character in length. I've tried casting and converting to make certain that the value was what I was expecting in the case statement when compared to 'Y'. I've tried concatenating a '>' and '<' to either side to see if somehow there were whitespaces padding the value, and that was not the case at all. It just appears as though the case statement simply ceased working. Here is a small sample of what the data looked like, to give you an idea of what it was working with...sorry it's a little bit scrambled.
WO_TASK_ID WO_ID ENS_TSK_CRT_VAL ENS_TSK_CRT_V01 ENS_TSK_CRT_V02 ENS_TSK_CRT_V03
1 0000002151 2 Y N N
9 0000002151 12 N Y Y
12 0000002151 52 N Y N
I've since fixed the problem by taking a completely different route, but I just want to know how this is happening, and what to do to overcome the problem in the future when working with the CASE Expression again.
Any help is greatly appreciated...
Flynn
Possible this be helpful for you -
;WITH cte AS
(
SELECT A.BUSINESS_UNIT ,
A.WO_TASK_ID ,
C.DESCR ,
A.WO_ID ,
C.ENS_TSK_CRT_CD
FROM PS_ENS_WM_TSKCR_VW A ,
PS_ENS_WM_TSK_CRT C
WHERE A.ENS_TSK_CRT_V01 = 'Y'
AND C.SETID = 'SHARE'
AND C.ENS_TSK_CRT_CD IN (
'01', '02', '03', '04',
'05', '06', '07', '08'
)
)
SELECT A.BUSINESS_UNIT ,
A.WO_ID ,
A.WO_TASK_ID ,
A.ENS_TSK_CRT_VAL ,
ISNULL(B.DESCR, ' ') AS ENS_TSK_CRT_V01 ,
ISNULL(C.DESCR, ' ') AS ENS_TSK_CRT_V02 ,
ISNULL(D.DESCR, ' ') AS ENS_TSK_CRT_V03 ,
ISNULL(E.DESCR, ' ') AS ENS_TSK_CRT_V04 ,
ISNULL(F.DESCR, ' ') AS ENS_TSK_CRT_V05 ,
ISNULL(G.DESCR, ' ') AS ENS_TSK_CRT_V06 ,
ISNULL(H.DESCR, ' ') AS ENS_TSK_CRT_V07 ,
ISNULL(I.DESCR, ' ') AS ENS_TSK_CRT_V08
FROM PS_ENS_WM_TSKCR_VW A
LEFT JOIN cte B ON B.BUSINESS_UNIT = A.BUSINESS_UNIT
AND B.WO_ID = A.WO_ID
AND B.WO_TASK_ID = A.WO_TASK_ID
AND B.ENS_TSK_CRT_CD = '01'
AND A.ENS_TSK_CRT_V01 = 'Y'
LEFT JOIN cte C ON C.BUSINESS_UNIT = A.BUSINESS_UNIT
AND C.WO_ID = A.WO_ID
AND C.WO_TASK_ID = A.WO_TASK_ID
AND C.ENS_TSK_CRT_CD = '02'
AND A.ENS_TSK_CRT_V02 = 'Y'
LEFT JOIN cte D ON D.BUSINESS_UNIT = A.BUSINESS_UNIT
AND D.WO_ID = A.WO_ID
AND D.WO_TASK_ID = A.WO_TASK_ID
AND D.ENS_TSK_CRT_CD = '03'
AND A.ENS_TSK_CRT_V03 = 'Y'
LEFT JOIN cte E ON E.BUSINESS_UNIT = A.BUSINESS_UNIT
AND E.WO_ID = A.WO_ID
AND E.WO_TASK_ID = A.WO_TASK_ID
AND E.ENS_TSK_CRT_CD = '04'
AND A.ENS_TSK_CRT_V04 = 'Y'
LEFT JOIN cte F ON F.BUSINESS_UNIT = A.BUSINESS_UNIT
AND F.WO_ID = A.WO_ID
AND F.WO_TASK_ID = A.WO_TASK_ID
AND F.ENS_TSK_CRT_CD = '05'
AND A.ENS_TSK_CRT_V05 = 'Y'
LEFT JOIN cte G ON G.BUSINESS_UNIT = A.BUSINESS_UNIT
AND G.WO_ID = A.WO_ID
AND G.WO_TASK_ID = A.WO_TASK_ID
AND G.ENS_TSK_CRT_CD = '06'
AND A.ENS_TSK_CRT_V06 = 'Y'
LEFT JOIN cte H ON H.BUSINESS_UNIT = A.BUSINESS_UNIT
AND H.WO_ID = A.WO_ID
AND H.WO_TASK_ID = A.WO_TASK_ID
AND H.ENS_TSK_CRT_CD = '07'
AND A.ENS_TSK_CRT_V07 = 'Y'
LEFT JOIN cte I ON I.BUSINESS_UNIT = A.BUSINESS_UNIT
AND I.WO_ID = A.WO_ID
AND I.WO_TASK_ID = A.WO_TASK_ID
AND I.ENS_TSK_CRT_CD = '08'
AND A.ENS_TSK_CRT_V08 = 'Y'
WHERE A.ENS_TSK_CRT_VAL != 0
AND A.WO_ID = '0000002151'
AND A.BUSINESS_UNIT = 'R3851'
BTW, just in case anyone is curious, here was the workaround I used before posting my question about the CASE Expression to the original problem......
SELECT A.BUSINESS_UNIT , A.WO_ID , A.WO_TASK_ID , A.ENS_TSK_CRT_VAL
, (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,1) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 01 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL01
, (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,2) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 02 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL02
, (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,3) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 03 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL03
, (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,4) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 04 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL04
, (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,5) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 05 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL05
, (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,6) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 06 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL06
, (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,7) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 07 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL07
, (CASE WHEN (CASE WHEN CAST(A.ENS_TSK_CRT_VAL AS INT) & POWER(2,8) > 0 THEN 1 ELSE 0 END) = 1 THEN (SELECT DESCR FROM PS_ENS_WM_TSK_CRT WHERE ENS_TSK_CRT_CD = 08 AND SETID = 'SHARE') ELSE ' ' END) AS ENS_TSK_CRT_VAL08
FROM PS_ENS_WM_TSKCR_WO A
WHERE A.ENS_TSK_CRT_VAL <> 0
AND A.WO_ID = '0000002151' AND A.BUSINESS_UNIT = 'R3851'
I suspect it is the behavior of the case statement. I just discovered a difference in 2008 R2 vs 2005 and in my searches came upon your problem. Case is handled by sql server 2008 R2 differently than 2005. Note the statement in the remarks of the 2008 doc: "In some situations, an expression is evaluated before a CASE statement receives the results of the expression as its input. Errors in evaluating these expressions are possible."
So in 2008 all potential outputs may be evaluated even if not appropriate (the input doesn't evaluate to true), which is occuring in some stored procs of mine now after upgrading to 2008.
So perhaps in your case, regardless of whether B.DESCR, C.DESCR, D.DESCR, etc. equal 'Y',
B.DESCR, C.DESCR, D.DESCR, etc. get evaluated and may at that time be null or otherwise somehow unable to be compared to 'Y' thereby causing that part of the statement to fail (and this is silent it seems). Not sure but it smells the same as what I had for a problem. The only thing that makes me cautious about this "answer" is that my problem was within the where clause and yours is in the select part of the sql statement.
Regardless, maybe someone will find this helpful. It took some digging to figure this out.
you can try to remove trailing space from Y which can cause similar issues

inner query to return more than one row

I am using oracle 11i in sql developer..
this is my query:
SELECT itm.stu_no,wm_concat(uif.names)
FROM personal uif,Coll itm, Dep ihts
WHERE uif.stu_id IN('26', '29', '32')
and (uif.stu_no,uif.stu_no) in
(
select itm.stu_no,itm.stu_test_no
from Col itm,Dep ihts
where itm.stu_no = ihts.stu_no
AND itm.status = 'A'
AND ihts.status = 'A'
)
AND itm.status = 'A'
and itm.stu_no=ihts.stu_no and ihts.status = 'A'
group by itm.stu_no;
the inner query (marked as strong text) returns...
stu_no stu_test_no
-----------------------------------
123 234
but the complete query is not returning any rows.
this is the expected result..
stu_no wm_concat(names)
------------------------------------------
123 James Alex
234 (null)
Is there any way to get the expected result?
It doesn't work because you're asking uif.stu_no to be both 123 and 234:
(123,123) is not in ((123,234))
and
(234,234) is not in ((123,234))
you can try this:
SELECT itm.stu_no,wm_concat(uif.names)
FROM personal uif,Coll itm, Dep ihts
WHERE uif.stu_id IN('26', '29', '32')
and uif.stu_no in
(
select itm.stu_no
from Col itm,Dep ihts
where itm.stu_no = ihts.stu_no
AND itm.status = 'A'
AND ihts.status = 'A'
union all
select itm.stu_test_no
from Col itm,Dep ihts
where itm.stu_no = ihts.stu_no
AND itm.status = 'A'
AND ihts.status = 'A'
)
AND itm.status = 'A'
and itm.stu_no=ihts.stu_no and ihts.status = 'A'
group by itm.stu_no;
But why not:
SELECT itm.stu_no,wm_concat(uif.names)
FROM personal uif, Coll itm, Dep ihts
WHERE uif.stu_id IN('26', '29', '32')
and (uif.stu_no = itm.stu_no OR uif.stu_no = itm.stu_test_no)
AND itm.status = 'A'
and itm.stu_no = ihts.stu_no
and ihts.status = 'A'
group by itm.stu_no;