Complex Query SQL - sql

I am currently working on an sql query where i am receiving data in three different rows, i really need the data in one single row
SELECT
substring(D.F1056, patindex('%[^0]%',D.F1056), 10) as Shop_Number,
REPLACE(CONVERT(VARCHAR(10), D.F254, 103), '/', '') AS Todays_Date,
SDP_TAB.F03 as Rayon,
[SDP_TAB].F04 as Famille,
CASE
WHEN D.F1034=3 THEN SUM(D.F64)
ELSE 0
END as Qty_Sold ,
CASE
WHEN D.F1034=3 THEN convert(DOUBLE PRECISION, SUM(D.F65)*100) * 10
ELSE 0
END as chiffre_daffaire_Caisse,
0 as montant_remisse_caisse,
CASE
WHEN D.F1034=3011 THEN SUM(D.F64)
WHEN D.F1034=3012 THEN SUM(D.F64)
ELSE 0
END as Qty_retour,
CASE
WHEN D.F1034=3011 THEN SUM(D.F65)
WHEN D.F1034=3012 THEN SUM(D.F65)
ELSE 0
END as Montant_Retour,
0 as Quantity,
CASE
WHEN D.F1034=3102 THEN SUM(D.F64)
ELSE 0
END as ClientCount,
F1034
FROM
[dbo].[RPT_ITM_D] D
LEFT OUTER JOIN [dbo].[POS_TAB] ON (D.F01=POS_TAB.F01)
LEFT OUTER JOIN [dbo].SDP_TAB ON (POS_TAB.F04=SDP_TAB.F04)
where
D.F1034 IN (3,3012,3011,3102)
AND
D.F254 = convert(varchar, getdate(), 101)
group by D.F1056,D.F254,SDP_TAB.F03,SDP_TAB.F04,D.F1034
My data is being populated as below
I am having three rows since i am having several condition for field F1034
Is there a way to have the expected result as below

Try this. (Using max with calculated columns)
With resultData as (
—Put your original query here
)
Select Shop_Number, Todays_Date,rayon,famille
,max(Qty_Sold) Qty_Sold, max(chiffre_daffaire_Caisse) chiffre_daffaire_Caisse
,max(montant_remisse_caisse) montant_remisse_caisse,max(Qty_retour) Qty_retour,max(Montant_Retour) Montant_Retour
,max(Quantity)Quantity,max(ClientCount) ClientCount,max(F1034) F1034
From resultData
group by Shop_Number, Todays_Date,rayon,famille

Related

compare two different date ranges sales in two columns

I want to compare two different date ranges sales in two columns.. I am using query below but its giving wrong sales.. please correct my query
select s1.Itm_cd,s1.Itm_Name,Sum(S1.amount),Sum(s2.amount)
from salestrans s1,salestrans s2
where s1.Itm_cd = S2.Itm_cd
and S1.Tran_dt between '20181101' and'20181130'
and S2.Tran_dt between '20171101' and '20171130'
group by s1.Itm_cd,s1.Itm_Name
Order by s1.Itm_cd
I suspect that you want conditional aggregation here:
WITH cte AS (
SELECT
s1.Itm_cd,
s1.Itm_Name,
SUM(CASE WHEN s1.Tran_dt BETWEEN '20181101' AND '20181130'
THEN s1.amount ELSE 0 END) AS sum_2018,
SUM(CASE WHEN s1.Tran_dt BETWEEN '20171101' AND '20171130'
THEN s1.amount ELSE 0 END) AS sum_2017
FROM salestrans s1
GROUP BY
s1.Itm_cd,
s1.Itm_Name
)
SELECT
Itm_cd,
Itm_Name,
sum_2018,
sum_2017,
CASE WHEN COALESCE(sum_2017, 0) <> 0
THEN FORMAT(100.0 * (sum_2018 - sum_2017) / sum_2017, 'N', 'en-us')
ELSE 'NA' END AS growth_pct
FROM cte
ORDER BY
Itm_cd;
Please try the following
select s1.Itm_cd,s1.Itm_Name,Sum(S1.amount),Sum(s2.amount)
from salestrans s1,salestrans s2
where s1.Itm_cd = S2.Itm_cd
and Convert(Varchar(10),S1.Tran_dt,112) between '20181101' and'20181130'
and Convert(Varchar(10),S2.Tran_dt,112) between '20171101' and '20171130'
group by s1.Itm_cd,s1.Itm_Name
Order by s1.Itm_cd
Here the logic is that in right side while comparision you are providing only date and not any separator and time. The same way should be applied to the column in left side for comparision.
if(Convert(Varchar(10), getdate(),112) = '20181224')
print 'Matched'
else
print 'Not Matched'
if(getdate() = '20181224')
print 'Matched'
else
print 'Not Matched'
Here the output is Matched for first and Not Matched because in first case both side same format has been taken for comparison.

Query works in SQL Developer but doesn't work in Putty (ORA-00907, missing parenthesis)

Can you see any telltale signs what this code is missing? I am sorry if this is too long. This is a full outer join of two segments, MTD and YTD. The results are expected are comma delimited. This works perfectly in SQL Developer but not in Unix (Putty).
select mtd.portfolio||','||
mtd.descr||','||
mtd.ccy||','||
CASE WHEN ytd.ytd_amnt IS NOT NULL THEN
CASE WHEN substr(mtd.acnt,1,1) in ('2','5','0') --base currency month to date
THEN (sum(ytd.ytd_amnt_bc) - sum(mtd.mtd_amnt_bc))*-1
ELSE (sum(ytd.ytd_amnt_bc) - sum(mtd.mtd_amnt_bc))
END
ELSE
0
END
||','||
CASE WHEN mtd.ccy in ('USD') THEN
CASE WHEN substr(mtd.acnt,1,1) in ('2','5','0') THEN --base currency year to date
sum(mtd.mtd_amnt)*-1
ELSE
sum(mtd.mtd_amnt)
END
ELSE
CASE WHEN substr(mtd.acnt,1,1)in ('2','5','0') THEN
sum(mtd.mtd_amnt_bc)*-1
ELSE
sum(mtd.mtd_amnt_bc)
END
END
||','||
CASE WHEN ytd.ytd_amnt IS NOT NULL THEN
CASE WHEN substr(mtd.acnt,1,1)in ('2','5','0') THEN --native currency month to date
(sum(ytd.ytd_amnt) - sum(mtd.mtd_amnt)) *-1
ELSE
sum(ytd.ytd_amnt) - sum(mtd.mtd_amnt)
END
ELSE
0
END||','||
CASE WHEN mtd.ccy in ('PHP') THEN --native currency year to date
CASE WHEN substr(mtd.acnt,1,1)in ('2','5','0') THEN
mtd.mtd_amnt*-1
ELSE
mtd.mtd_amnt
END
ELSE
CASE WHEN substr(mtd.acnt,1,1)in ('2','5','0') THEN
sum(mtd.mtd_amnt_bc)*-1
ELSE
sum(mtd.mtd_amnt_bc)
END
END||','||
CASE WHEN substr(mtd.acnt,1,1)='0'
THEN '5'
ELSE substr(mtd.acnt,1,1)
END
from
(select (accl.acnt) acnt, (kp.account) portfolio, (accc.descr)descr, (accl.curr) ccy, sum(accl.amnt_bc) mtd_amnt_bc, sum(accl.amnt) mtd_amnt
from acc$ledger accl
LEFT JOIN k$portfolio kp ON kp.id = accl.portfolio
LEFT JOIN acc$chart accc ON accc.acnt = accl.acnt
where accl.company = accc.company
and accl.company <> 1
and substr(accl.acnt,1,1) in ('0','1','2','5')
and accc.fisc_yr in (select to_char(current_business_date,'YYYY') from k$company where id=1)
and accl.account_dte <> to_date('0001-01-01','YYYY-MM-DD')
and accl.dt <= (select last_day(add_months(current_business_date,-1)) from k$company where id=1)
group by accc.descr, kp.account, accl.acnt, accl.curr
order by kp.account, accl.acnt
)
mtd full outer join
(select (accl.acnt) acnt, (kp.account) portfolio, (accc.descr)descr, sum(accl.amnt_bc) ytd_amnt_bc, sum(accl.amnt) ytd_amnt
from acc$ledger accl
LEFT JOIN k$portfolio kp ON kp.id = accl.portfolio
LEFT JOIN acc$chart accc ON accc.acnt = accl.acnt
where accl.company = accc.company
and accl.company <> 1
and substr(accl.acnt,1,1) in ('0','1','2','5')
and accc.fisc_yr in (select to_char(current_business_date,'YYYY') from k$company where id=1)
and accl.account_dte <> to_date('0001-01-01','YYYY-MM-DD')
and accl.dt <= (select last_day(add_months(current_business_date,-2)) from k$company where id=1)
group by accc.descr, kp.account, accl.acnt
order by kp.account, accl.acnt)
ytd
on mtd.portfolio=ytd.portfolio
and mtd.descr=ytd.descr
and mtd.acnt= ytd.acnt
group by mtd.acnt, mtd.portfolio, mtd.descr, mtd.ccy, mtd.mtd_amnt, ytd.ytd_amnt
order by mtd.portfolio, mtd.acnt, mtd.descr;
Remove the empty newline. By default SQL*Plus uses empty newlines to terminate a SQL statement. SQL Developer does not work the same way, depending on how you run the query.

Result showing two rows to one row

I wrote a query to count positive and negative results per day. My problem is that I am getting two rows per postivie to negative day.
I want one row with a positive and negative column for each day( no multiple days).
SELECT case([MsrSplatPositive]) when '0' then count([MsrSplatPositive]) end as 'Negative'
,case([MsrSplatPositive]) when '1' then count([MsrSplatPositive]) end as 'Positive'
,CONVERT(VARCHAR(10), f.NewsDate, 106) as 'Date'
FROM [News].[dbo].[Score] s
inner join [News].[dbo].[Feed] f
on f.ScoreId = s.Id
where f.NewsDate between dateadd(day,-30,GETDATE()) and GETDATE()
group by [MsrSplatPositive],CONVERT(VARCHAR(10), f.NewsDate, 106)
Remove MsrSplatPositive from the GROUP BY.
That is forcing the positive and negative results into different days.
And then use a SUM(CASE...) instead of CASE(COUNT...)
You have this in the SELECT:
case([MsrSplatPositive]) when '0' then count([MsrSplatPositive]) end as 'Negative'
and instead want this:
sum(CASE WHEN MsrSplatPositive = 0 THEN 1 ELSE 0 END) as 'Negative'
EDIT:
All fixed up should be something like:
SELECT SUM(CASE WHEN MsrSplatPositive = 0 THEN 1 ELSE 0 END) 'Negative'
,SUM(MsrSplatPositive 'Positive'
,CONVERT(VARCHAR(10), f.NewsDate, 106) as 'Date'
FROM News.dbo.Score s
INNER JOIN
News.dbo.Feed f on f.ScoreId = s.Id
WHERE f.NewsDate BETWEEN DATEADD(DAY,-30,GETDATE()) and GETDATE()
GROUP BY f.NewsDate
Try this...I haven't run the query but think this should achieve the result. I have modified your original query to return 0 instead of null in the positive and negative column. Then used the modified SQL as a temp table and grouped by the date values.
Select Sum(Temp.Negative), Sum(Temp.Positive), Temp.Date From
(
SELECT case([MsrSplatPositive]) when '0' then count([MsrSplatPositive])
else 0 end as 'Negative'
,case([MsrSplatPositive]) when '1' then count([MsrSplatPositive]
else 0) end as 'Positive'
,CONVERT(VARCHAR(10), f.NewsDate, 106) as 'Date'
FROM [News].[dbo].[Score] s
inner join [News].[dbo].[Feed] f
on f.ScoreId = s.Id
where f.NewsDate between dateadd(day,-30,GETDATE()) and GETDATE()
group by [MsrSplatPositive],CONVERT(VARCHAR(10), f.NewsDate, 106)
) Temp
Group By Temp.Date
Hope this helps.

Transact-SQL Sub Query

I'm struggling to find the logic of how to accomplish a sub query, or at least that's what I think is required! I'll show what I have:
SELECT CH.SFA,
convert(datetime, RE.START_DATE, 103) AS 'START DATE',
Count(Distinct CH.CHNO) AS 'TOTAL CH',
Count(CH.STATUS) AS 'COMPLETED CH',
count(distinct CH.CHNO + CH.STATUS) As 'COMPLETED CH2'
FROM CUSTOMER.dbo. CH CH, CUSTOMER.dbo.RE RE
WHERE
RE.SFA = CH.SFA
GROUP BY
CH.SFA, RE.START_DATE
What I am trying to do is where I have COMPLETED CH2 I need to specify that it ends with a C, the Status Column is either blanks or C's and by doing a distinct count of CHNO and C together give me the result I need but I cannot for the life of me find out how to write it!
I am using Microsoft Query to take the data from its source straight into the Excel spreadsheet.
Many thanks for taking a look.
Been ages since I've used MS Query so I'm fuzzy on syntax, but this is the general idea of how to write a subquery containing a WHERE clause and an aggregation to get you started:
SELECT
CH.SFA,
convert(datetime, RE.START_DATE, 103) AS 'START DATE',
Count(DISTINCT CH.CHNO) AS 'TOTAL CH',
Count(CH.STATUS) AS 'COMPLETED CH',
CCH.COMPLETED_CH2 AS 'COMPLETED CH2'
FROM CUSTOMER.dbo.CH CH
INNER JOIN CUSTOMER.dbo.RE RE
ON RE.SFA = CH.SFA
LEFT JOIN (
SELECT SFA, COUNT(DISTINCT CH.CHNO) AS COMPLETED_CH2
FROM CUSTOMER.dbo.CH
WHERE STATUS = 'C'
GROUP BY SFA
) AS CCH
ON RE.SFA = CCH.SFA
GROUP BY CH.SFA, RE.START_DATE
if you just want to know count of records where CH.STATUS = 'C' than add another COUNT statement with CASE logic.
COUNT(CASE WHEN CH.STATUS = 'C' then 1 else null end) as 'COMPLETED CH2'
when combining COUNT and CASE statement remember to have NULL for ELSE statement, otherwise all rows will be counted.
as an alternative you can do it with a SUM
SUM(CASE WHEN CH.STATUS = 'C' then 1 else 0 end) as 'COMPLETED CH2'

Can't get PIVOT to work

I am trying to use PIVOT for the first time and I am not able to get it to work, I just can't seem to figure out what I am doing wrong.
I started with a nasty select statement. When I get these results I can get results and what I have been doing is exporting to Excel and using the pivot functions in there. When I get the data into Excel, I do this as my operations: http://imgur.com/N024rEi
So I then went to the next step and tried to do the whole pivot in SQL but can't get it to work. Here is my code:
SELECT DISTINCT #tmp1.AuthID
, #tmp1.ProviderID
, #tmp1.ProviderName
, #tmp1.LOCID
, #tmp1.LOCDesc
, '$' + CONVERT(VARCHAR,CAST(#tmp1.TotAuthAmt AS MONEY),-1) AS 'ToAuthAmt'
, CONVERT(VARCHAR(10), #tmp1.AuthDate, 101) AS AuthDate,
CONVERT(VARCHAR(10), #tmp1.AuthExpirationDate, 101) AS AuthExpirationDate
, DATEDIFF(D,#tmp1.AuthDate,#tmp1.AuthExpirationDate) AS AuthLenInDays
, (CASE WHEN
ISNULL(#tmp2.TotPaidAmt, 0) = 0 THEN '$0.00'
ELSE '$' + CONVERT(VARCHAR,CAST(#tmp2.TotPaidAmt AS MONEY),-1)
END) AS TotPaidAmt,
#tmp1.NbrOfAuthorizations
, #tmp1.UnitsAuthorized
, #tmp1.RatePerUnit
, #tmp1.CAREMODE
, (CASE WHEN
ISNULL(#tmp2.UnitsAdjudicated, 0) = 0 THEN 0
ELSE #tmp2.UnitsAdjudicated
END) AS AuthUnitsClaimed
, (#tmp1.UnitsAuthorized -
(CASE WHEN
ISNULL(#tmp2.UnitsAdjudicated, 0) = 0 THEN 0
ELSE #tmp2.UnitsAdjudicated
END)) AS UnclaimedAuths
, (CASE WHEN
ISNULL(#tmp2.ExpiredAuths, 0) = 0 THEN 0
ELSE 1
END) AS ExpiredIndicator
FROM (SELECT
DISTINCT #tmp1.AuthID
, #tmp1.ProviderID
, #tmp1.ProviderName
, #tmp1.LOCID
, #tmp1.LOCDesc
, '$' + CONVERT(VARCHAR,CAST(#tmp1.TotAuthAmt AS MONEY),-1) AS 'ToAuthAmt'
, CONVERT(VARCHAR(10), #tmp1.AuthDate, 101) AS AuthDate
, CONVERT(VARCHAR(10), #tmp1.AuthExpirationDate, 101) AS AuthExpirationDate
, DATEDIFF(D,#tmp1.AuthDate,#tmp1.AuthExpirationDate) AS AuthLenInDays
, (CASE WHEN
ISNULL(#tmp2.TotPaidAmt, 0) = 0 THEN '$0.00'
ELSE '$' + CONVERT(VARCHAR,CAST(#tmp2.TotPaidAmt AS MONEY),-1)
END) AS TotPaidAmt,
#tmp1.UnitsAuthorized
, #tmp1.RatePerUnit
, #tmp1.CAREMODE
, (CASE WHEN
ISNULL(#tmp2.UnitsAdjudicated, 0) = 0 THEN 0
ELSE #tmp2.UnitsAdjudicated
END) AS AuthUnitsClaimed
, (#tmp1.UnitsAuthorized -
(CASE WHEN
ISNULL(#tmp2.UnitsAdjudicated, 0) = 0 THEN 0
ELSE #tmp2.UnitsAdjudicated
END)) AS UnclaimedAuths
, (CASE WHEN
ISNULL(#tmp2.ExpiredAuths, 0) = 0 THEN 0
ELSE 1
END) AS ExpiredIndicator
FROM #tmp1
LEFT JOIN #tmp2
ON #tmp2.AuthID = #tmp1.AuthID
GROUP BY #tmp1.AuthID, #tmp1.ProviderID, #tmp1.LOCID, #tmp1.LOCDesc, #tmp1.UnitsAuthorized, #tmp1.RatePerUnit, #tmp1.FamilyID, #tmp1.ProviderName, #tmp1.TotAuthAmt,
#tmp1.AuthDate, #tmp1.AuthExpirationDate, #tmp2.TotPaidAmt, #tmp1.NbrOfAuthorizations, #tmp1.CAREMODE, #tmp2.UnitsAdjudicated, #tmp2.ExpiredAuths
)#tmp1
PIVOT (
SUM(#tmp1.NbrOfAuthorizations) FOR ProviderName
IN (#tmp1.ProviderName)
) AS #tmp1
What do I need to change here to get this to work? Also, how would I add the other items as shown in the screen shot?
EDIT1: Looks like I was able to get results after using this for my PIVOT:
PIVOT
(SUM(NbrOfAuthorizations) FOR [ProviderName] IN (element1, element2, etc.)
) PivotResults1
PIVOT
(AVG(AuthLenInDays) FOR [CAREMODE] IN ([element1])
) PivotResults2
but still having a couple of issues...the SUM statement doesn't actually seem to SUM the values for a specific value into one column. I see a '1' or NULL for each cell, as in this example: http://www.codeproject.com/Tips/500811/Simple-Way-To-Use-Pivot-In-SQL-Query . The other thing is for my AVG column, I can't figure out how to change the name of that column, it is always the name of element1.
i think instead of
IN (#tmp1.ProviderName)
you need
IN ([element1],[element2],[element3], ... )
with element*n* being all variations of content of #tmp1.ProviderName. In the SELECT part at the very top you must then list these elements as columns
and
you should give different aliases to the two table statements, you have #tmp1 twice in there.
Try an easy test example of PIVOT with much less columns first. If You figure it out it is very powerful. I love the pivot features in excel (pivotcharts!) but the database can do aggregation so much faster.