Case sql not working - sql

I have a select statement I am trying to make for a report. I have it pulling data and everything I need but I noticed that since I have to use the group by it is dropping off rows that do not exist in a table. How can I stop this or make it work.
SELECT Sum(CASE WHEN direction = 'I' THEN 1 ELSE 0 END) InBound,
Sum(CASE WHEN direction = 'O' THEN 1 ELSE 0 END) OutBound,
Sum(CASE WHEN direction = 'I' THEN p.duration ELSE 0 END) InBoundTime,
Sum(CASE WHEN direction = 'O' THEN p.duration ELSE 0 END) OutBoundTime,
u.fullname,
( CASE
WHEN EXISTS (SELECT g.goalamount
FROM [tblbrokergoals] AS g
WHERE ( g.goaldate BETWEEN
'2016-03-21' AND '2016-03-27' ))
THEN
g.goalamount
ELSE 0
END ) AS GoalAmount
FROM [tblphonelogs] AS p
LEFT JOIN [tblusers] AS u
ON u.fullname = p.phonename
LEFT OUTER JOIN [tblbrokergoals] AS g
ON u.fullname = g.brokername
WHERE ( calldatetime BETWEEN '2016-03-21' AND '2016-03-27' )
AND ( u.userid IS NOT NULL )
AND ( u.direxclude <> '11' )
AND u.termdate IS NULL
AND ( g.goaldate BETWEEN '2016-03-21' AND '2016-03-27' )
GROUP BY u.fullname,
g.goalamount;
This works and grabs all the data when the user is in BrokerGoals but, when the user is not in broker goals it just deletes that row on the returned result set. How can I get it so when the user doesnt not exist in the brokergoals table to set that value as 0 or -- so the row does not get deleted.

If you have a brokers table then you can use it for your left join
SELECT b.broker_id, ....
FROM brokers b
LEFT JOIN .... ALL YOUR OTHER TABLES
....
GROUP BY b.broker_id, ....
If your brokers has duplicate names then use
SELECT b.broker_id, ....
FROM (SELECT DISTINCT broker_id
FROM brokers) b
LEFT JOIN .... ALL YOUR OTHER TABLES
....
GROUP BY b.broker_id, ....

SELECT u.FullName,
SUM(CASE WHEN Direction = 'I' THEN 1 ELSE 0 END) AS InBound,
SUM(CASE WHEN Direction = 'O' THEN 1 ELSE 0 END) OutBound,
SUM(CASE WHEN Direction = 'I' THEN p.Duration ELSE 0 END) InBoundTime,
SUM(CASE WHEN Direction = 'O' THEN p.Duration ELSE 0 END) OutBoundTime,
CASE WHEN EXISTS (
SELECT g.GoalAmount
FROM [Portal].[dbo].[tblBrokerGoals] AS g
WHERE g.GoalDate BETWEEN '2016-03-21' AND '2016-03-27'
AND u.FullName = g.BrokerName
) THEN (
SELECT g.GoalAmount
FROM [Portal].[dbo].[tblBrokerGoals] AS g
WHERE g.GoalDate BETWEEN '2016-03-21' AND '2016-03-27'
AND u.FullName = g.BrokerName
) ELSE '0' END AS GoalAmount
FROM [Portal].[dbo].[tblUsers] AS u
LEFT JOIN [Portal].[dbo].[tblPhoneLogs] AS p
ON u.FullName = p.PhoneName
WHERE u.UserID IS NOT NULL
AND u.DirExclude <> '11'
AND u.TermDate IS NULL
AND p.CallDateTime BETWEEN '2016-03-21' AND '2016-03-27'
GROUP BY u.FullName
This is what I ended up doing to fix my problem. I added the Case When Exists statement and in the then statement did the select else it is 0.

Have you tried replacing ( CASE
WHEN EXISTS (SELECT g.goalamount
FROM [tblbrokergoals] AS g
WHERE ( g.goaldate BETWEEN
'2016-03-21' AND '2016-03-27' ))
THEN
g.goalamount
ELSE 0
END ) AS GoalAmount
to just g.goalamount, as you already have that date condition in where clause

Related

using Query one results to run Query two

SELECT distinct
Pd.Cpd as ' accountnumber'
FROM [RQL_ALK_PMT].[Cts_opps] pd
INNER JOIN [RQL_ALK_PMT].[Cts_opps].dpo.cnms_id metg on metg.cnms_id=me.cnms_id
This code would result with this
Result
accountnumber
1332132
3213123
5641202
6412221
1233242
What I would like to do is when the code above gets the results my bottom code reads them and runs them trough its code. The common denominator here would be the account number because its running through a different table
SELECT
pm.AcctNumb as 'accountnumber'
, SUM(CASE WHEN pm.cusidIN ('cr') THEN 1 ELSE 0 END) AS CA
, SUM(CASE WHEN pm.cusidIN ('gb') THEN 1 ELSE 0 END) AS GB
, SUM(CASE WHEN pm.cusidIN ('tev','offev','Lastev') THEN 1 ELSE 0 END) AS chr
, SUM(CASE WHEN pm.cusidIN
('pm','pr','che' )
THEN 1 ELSE 0 END) AS Act
, SUM(CASE WHEN pm.cusidIN ('supev','tev') THEN 1 ELSE 0 END) AS Fulfillment
FROM ops.medadata pm WITH (NOLOCK)
INNER JOIN mw.pim_acct Ma with (nolock) ON ma.AcctNumb= pm.AcctNumb
Where pm.AcctNumb in ()
GROUP BY
pm.AcctNumb
I have tried doing this the code below but it doesnt seem to work
With counta as (
SELECT distinct
Pd.Cpd as ' accountnumber'
FROM [RQL_ALK_PMT].[Cts_opps] pd
INNER JOIN [RQL_ALK_PMT].[Cts_opps].dpo.cnms_id metg on metg.cnms_id=me.cnms_id
)
SELECT
pm.AcctNumb as 'accountnumber'
, SUM(CASE WHEN pm.cusidIN ('cr') THEN 1 ELSE 0 END) AS CA
, SUM(CASE WHEN pm.cusidIN ('gb') THEN 1 ELSE 0 END) AS GB
, SUM(CASE WHEN pm.cusidIN ('tev','offev','Lastev') THEN 1 ELSE 0 END) AS chr
, SUM(CASE WHEN pm.cusidIN
('pm','pr','che' )
THEN 1 ELSE 0 END) AS Act
, SUM(CASE WHEN pm.cusidIN ('supev','tev') THEN 1 ELSE 0 END) AS Fulfillment
FROM ops.medadata pm WITH (NOLOCK)
INNER JOIN mw.pim_acct Ma with (nolock) ON ma.AcctNumb= pm.AcctNumb
left join counta on Pm.accountnumber = counta.accountnumber
Where pm.AcctNumb in (counta.accountnumber)
GROUP BY
pm.AcctNumb
**im having issue with joining the two tables together**
IN is not an equivalent to a join - but you are treating that way.
Instead think of "IN this LIST" and the list could be supplied by you, or by a subquery e.g.
a list given by the query itself
select * from atable
where acol IN ('a','b','c') -- i.e. the list is hardcoded
or, using a subquery
SELECT ...etc.
WHERE pm.AcctNumb IN (
SELECT Pd.Cpd
FROM [RQL_ALK_PMT].[Cts_opps] pd
INNER JOIN [RQL_ALK_PMT].[Cts_opps].dpo.cnms_id metg on metg.cnms_id=me.cnms_id
)
or, if using a CTE
With counta as (
SELECT Pd.Cpd
FROM [RQL_ALK_PMT].[Cts_opps] pd
INNER JOIN [RQL_ALK_PMT].[Cts_opps].dpo.cnms_id metg on metg.cnms_id=me.cnms_id
)
SELECT ... etc.
WHERE pm.AcctNumb IN (
SELECT Cpd
FROM counta
)
note, it usually is not more efficient to use select distinct when forming a subquery to be used with an IN list.

Using an array in conditional summation with grouping

I have the sql query thats work fine
SELECT
CAST(L.CreationUtcDateTime AS DATE),
SUM(L.Profit),
SUM(CASE WHEN (L.Network = 0 OR L.Network = 1) THEN L.Profit ELSE 0 END),
SUM(CASE WHEN (L.Network != 0 AND L.Network != 1) THEN L.Profit ELSE 0 END)
FROM
[dbo].[Leads] L WITH (NOLOCK)
LEFT JOIN [dbo].[Transactions] S WITH (NOLOCK) ON L.TransactionId = S.Id
GROUP BY
CAST(L.CreationUtcDateTime AS DATE);
I need to make it more generic by using variables instead of hard-coded constants.
I changed the query to:
DECLARE #matchNetworks TABLE (id int)
INSERT #matchNetworks(id) VALUES (0),(1)
SELECT
CAST(L.CreationUtcDateTime AS DATE),
SUM(L.Profit),
SUM(CASE WHEN (L.Network in (SELECT ID from #matchNetworks)) THEN L.Profit ELSE 0 END),
SUM(CASE WHEN (L.Network not in (SELECT ID from #matchNetworks)) THEN L.Profit ELSE 0 END)
FROM
[dbo].[Leads] L WITH (NOLOCK)
LEFT JOIN [dbo].[Transactions] S WITH (NOLOCK) ON L.TransactionId = S.Id
GROUP BY
CAST(L.CreationUtcDateTime AS DATE);
And now i have an error:
Cannot perform an aggregate function on an expression containing an aggregate or a subquery.
How can I use the predefined array of network ids in my query to avoid an error?
Move the comparison to the FROM clause using a LEFT JOIN:
SELECT CAST(L.CreationUtcDateTime AS DATE),
SUM(L.Profit),
SUM(CASE WHEN mn.ID IS NOT NULL THEN L.Profit ELSE 0 END),
SUM(CASE WHEN mn.ID IS NULL THEN L.Profit ELSE 0 END)
FROM [dbo].[Leads] L LEFT JOIN
[dbo].[Transactions] S
ON L.TransactionId = S.Id LEFT JOIN
#matchNetworks mn
ON mn.ID = l.Network
GROUP BY CAST(L.CreationUtcDateTime AS DATE);

Joining multiple tables results in duplicate rows

There are tow tables (Customer & Feedback) that have different information. The following query is almost correct, except that it results in duplicate rows. I only need unique rows as par customerId and NO for null value.
I tried the GROUP BY clause at the end but it gives error.
Select C.CustomerId,
C.FirstName,
C.LastName,
(SELECT CAST(CASE WHEN F.Id != null or F.Type = 'Query'
THEN 'YES' ELSE 'NO' END AS NVARCHAR(50))) as Query,
(SELECT CAST(CASE WHEN F.Id != null or F.Type = 'Feedback'
THEN 'YES' ELSE 'NO' END AS NVARCHAR(50))) as Feedback
FROM Customer C
LEFT JOIN Feedback F on F.CustomerId= C.CustomerId
Select * from Customer
Select * from Feedback
As Result I want to display only single row by customerId and to join the feedback table data like below...
You May Try either of the Below
SELECT
C.*,
Query = CASE WHEN PVT.Query IS NOT NULL THEN 'Yes' ELSE 'No' END,
Feedback = CASE WHEN PVT.Feedback IS NOT NULL THEN 'Yes' ELSE 'No' END
FROM Customer C
LEFT JOIN FeedBack
PIVOT
(
MAX(Id)
FOR
[Type] IN
(
[Query],[Feedback]
)
)Pvt
ON PVT.CustomerId = c.CustomerId
or Simply
SELECT
C.*,
Query = CASE WHEN EXISTS(SELECT 1 FROM FeedBack WHERE CustomerId = C.CustomerId and [Type]='Query') THEN 'Yes' ELSE 'No' END,
Feedback = CASE WHEN EXISTS(SELECT 1 FROM FeedBack WHERE CustomerId = C.CustomerId and [Type]='Feedback') THEN 'Yes' ELSE 'No' END
FROM Customer C
To Make it more Dynamic ou may Try this
DECLARE #SQL VARCHAR(MAX)
;WITH CTE
AS
(
SELECT
RN = ROW_NUMBER() OVER(PARTITION BY [Type] ORDER BY [Type]),
QRY = LTRIM(RTRIM([Type]))+' = CASE WHEN EXISTS(SELECT 1 FROM FeedBack WHERE CustomerId = C.CustomerId and [Type]='''+LTRIM(RTRIM([Type]))+''') THEN ''Yes'' ELSE ''No'' END'
FROM FeedBack
)
SELECT
#SQL = 'SELECT
C.*'
+SUBSTRING(','+L.List,1,LEN(L.List)-1)
+' FROM Customer C'
FROM
(
SELECT
QRY + ', ' [text()]
FROM CTE
WHERE RN = 1
FOR XML PATH('')
)L(List)
EXEC(#SQL)
Please Refer this Sqlfiddle for detailed example
Select C.CustomerId,
C.FirstName,
C.LastName,
sum(case when F.Type = 'Query' then 1 else 0 end) > 0 as Query,
sum(case when F.Type = 'Feedback' then 1 else 0 end) > 0 as Feedback
FROM Customer C
LEFT JOIN Feedback F on F.CustomerId= C.CustomerId
GROUP BY C.CustomerId, C.FirstName, C.LastName
use case when
Select C.CustomerId,
C.FirstName,
C.LastName,
case when sum(case when F.Type = 'Query' then 1 else 0 end) > 0 then 'Yes' else 'NO' end as Query,
case when sum(case when F.Type = 'Feedback' then 1 else 0 end) > 0 then 'Yes' else 'NO' End as Feedback
FROM Customer C
LEFT JOIN Feedback F on F.CustomerId= C.CustomerId
GROUP BY C.CustomerId, C.FirstName, C.LastName
Try below query using subquery:
select *,case when query=1 then 'Yes' else 'No' end as query,
case when feedback=1 then 'Yes' else 'No' end as feedbackfrom
(select CustomerId, firstname,lastname,
sum(CASE WHEN Type = 'Query'
THEN 1 ELSE 0 END) as Query,
sum(CASE WHEN Type = 'Feedback'
THEN 1 ELSE 0 END) as Feedback from Customer C
LEFT JOIN Feedback F on F.CustomerId= C.CustomerId
group by CustomerId, firstname,lastname)a
Try this:
select c.CustomerId,
c.FirstName,
c.LastName,
case when q.CustomerId is null then 'NO' else 'YES' end Query,
case when f.CustomerId is null then 'NO' else 'YES' end Feedback,
from Customers c
left join (select customerId from Feedback where Type = 'Query' ) q on c.CustomerId = q.CustomerId
left join (select customerId from Feedback where Type = 'Feedback' ) f on c.CustomerId = q.CustomerId

Display query results using pivot

I have the below query which i to display the results using a PIVOT so that the results are displayed in one row.
With T1 As
(EXT Code
),
T2 AS (
SELECT p.SId, p.TransType, Amount =SUM(p.Amount)
FROM T1 p
GROUP BY p.SId, p.TransType
)
SELECT m.SNo, m.Name, t.TransType,
CASE WHEN t.TransType ='PAYCM' THEN t.Amount ELSE 0 END AS 'GROSS CM',
CASE WHEN t.TransType ='PAYYTD' THEN t.Amount ELSE 0 END AS 'GROSS YTD',
CASE WHEN t.TransType ='TAXCM' THEN t.Amount ELSE 0 END AS 'Tax CM',
CASE WHEN t.TransType ='TAXYTD' THEN t.Amount ELSE 0 END AS 'Tax YTD'
FROM Master m INNER JOIN T2 t ON t.PId = m.Id
If you want one row, then use aggregation and remove the non-aggregated columns:
SELECT SUM(CASE WHEN t.TransType = 'PAYCM' THEN t.Amount ELSE 0 END) AS GROSS _CM,
SUM(CASE WHEN t.TransType = 'PAYYTD' THEN t.Amount ELSE 0 END) AS GROSS_YTD,
SUM(CASE WHEN t.TransType = 'TAXCM' THEN t.Amount ELSE 0 END) AS Tax_CM,
SUM(CASE WHEN t.TransType = 'TAXYTD' THEN t.Amount ELSE 0 END) AS Tax_YTD
FROM Master m INNER JOIN
T2 t
ON t.PId = m.Id;

Complex Case Statement Issue - Oracle SQL

Wrote the query below, but am getting multiplied amounts because the aggregation needs to occur before the case statements. Would love some advice on the best way to structure this.
Select Store, CUSTID, CUST.ID_CUST,
Sum(
CASE
WHEN Cust_Gift.Code_Status = 'C' AND Gift_Item.FLAG_STORE_LOC = 'N'
THEN Cust_Gift.AMT_PAID ELSE 0
END) GiftAmt,
Sum(
CASE WHEN Cust_Gift.Code_Status = 'C' AND Gift_Item.FLAG_STORE_LOC = 'Y'
THEN Cust_Gift.AMT ELSE 0
END) CustGiftAmt,
Sum(
CASE WHEN Cust_Coupon.Code_Status = 'C'
THEN Cust_Coupon.AMT
ELSE 0
END) CouponAmt,
Sum(CASE WHEN Cust_Sports.Status = 'C'
THEN Cust_Sports.AMT
ELSE 0
END) SportsAmt
FROM CUST
LEFT OUTER JOIN CUST_GIFT
ON CUST.ID_CUST = CUST_GIFT.ID_CUST
LEFT OUTER JOIN CUST_COUPON
ON CUST.ID_CUST = CUST_COUPON.ID_CUST
LEFT OUTER JOIN CUST_SPORTS
ON CUST.ID_CUST = CUST_SPORTS.ID_CUST
INNER JOIN GIFT_ITEM
ON CUST_GIFT.ID_GIFT_ITEM = GIFT_ITEM.ID_GIFT_ITEM
WHERE (STORE = 'M669098' OR STORE = 'M66923434' )
Group by CustID, Store, CUST.ID_CUST
This is one way you could do it:
SELECT cust.store,
cust.custid,
cust.id_cust,
gift.giftamt,
gift.custgift,
cpn.couponamt,
sprt.sportsamt
FROM cust
LEFT OUTER JOIN (SELECT id_cust,
SUM(CASE WHEN cg.code_status = 'C' AND gi.flag_store_loc = 'N' THEN cg.amt_paid END) giftamt,
SUM(CASE WHEN cg.code_status = 'C' AND gi.flag_store_loc = 'Y' THEN cg.amt_paid END) custgiftamt
FROM cust_gift cg
INNER JOIN gift_item gi ON cg.id_gift_item = gi.id_gift_item) gift ON cust.id_cust = gift.id_cust
LEFT OUTER JOIN (SELECT id_cust,
SUM(CASE WHEN code_status = 'C' THEN amt END) couponamt
FROM cust_coupon) cpn ON cust.id_cust = cpn.id_cust
LEFT OUTER JOIN (SELECT id_cust,
SUM(CASE WHEN status = 'C' THEN amt END) sportsamt
FROM cust_sports) sprt ON cust.id_cust = sprt.id_cust
WHERE (STORE = 'M669098' OR STORE = 'M66923434');