In SSRS How to make a sequential Group Column - sql

I want to make a Sequential Group Column with the help of Matrix in SQL Server Reporting Service (SSRS),
In the image above, there are Dates with Days name, Mon 24, Tue 25 and Fri 28, So I want to make it like that: Keep the sequence of Dates, no matter whether the data is available or not.
My SQL Query for generating that data is:
SELECT tl.[Job No_] + ' - ' + j.[Description] AS [Job Name]
,tl.[Job Task No_] + ' - ' + w.[Description] AS [WBS Code]
,pt.[Description] AS [Pay Type]
,tlt.[Period Date]
,tlt.[Hours] AS [Hours]
FROM TimesheetLine tl
JOIN TimesheetLineDate tld ON tl.[Rec ID] = tld.[Timesheet Line Rec ID]
JOIN TimesheetLineTransactions tlt ON tld.[Rec ID] = tlt.[Timesheet Line Date Rec ID]
LEFT JOIN Job j ON tl.[Job No_] = j.[No_]
LEFT JOIN JobWBS w ON w.[Job Task No_] = tl.[Job Task No_]
LEFT JOIN PayType pt ON tl.[Pay Type] = pt.[Name]
LEFT JOIN Timesheet t ON tl.[Timesheet Rec ID] = t.[Rec ID]
WHERE tl.[Timesheet Rec ID] = #RecId AND t.[Resource No_] = #UserResourceNo

SSRS cannot generate data so you will need to solve this in your dataset.
I would add a right join to a table of Dates e.g. a Date/Time Dimension table. Then I would use the date from that table as the label and values for the SSRS Column Group.

Related

SQL: Grouping on a subquery

I have a query where I want to aggregate column ElementAantal. However this is the first time I am grouping on columns where there is a subquery ArtikelInhoud involved.
Please your advise on how to make the query work.
SELECT
pl.[Location Code] AS Locatie,
pl.[Ending Date] AS ProdOrderDatum,
pl.[Item No_] AS Artikelnr,
pl.Description AS Artikel,
pbl.No_ AS Elementnr,
pbl.Description AS Element,
SUM(pbl.Quantity * pl.Quantity) AS ElementAantal, -----> Aggregating this column
i.[Item Category Code] AS ElementCategorie,
(
SELECT Value
FROM [$Attribute Specification] att
WHERE [Table ID] = 27 AND Code = 'INH' AND att.[Unique Record Identifier] = i1.[Unique Record Identifier]
) AS ArtikelInhoud,
i.[Gross Weight] AS ElementGewicht,
v.Name AS Leverancier
FROM [$Prod_ Order Line] pl
LEFT JOIN [$Production BOM Line] pbl ON pl.[Production BOM No_] = pbl.[Production BOM No_]
LEFT JOIN [$Item] i ON pbl.No_ = i.No_
LEFT JOIN [$Item] i1 ON pl.[Item No_] = i1.No_
LEFT JOIN [$Vendor] v ON i.[Vendor No_] = v.No_
GROUP BY pl.[Location Code],
pl.[Ending Date],
pl.[Item No_],
pl.Description,
pbl.No_,
pbl.Description,
i.[Item Category Code],
(
SELECT Value
FROM [$Attribute Specification] att
WHERE [Table ID] = 27 AND Code = 'INH' AND att.[Unique Record Identifier] = i1.[Unique Record Identifier]
),
i.[Gross Weight],
v.Name

Error: The order by clause is invalid in views

I'm getting the following error in SQL Server 14 where I am trying to build a view based on 4 tables
The ORDER BY clause is invalid in views, inline functions, derived
tables, subqueries, and common table expressions, unless TOP, OFFSET
or FOR XML is also specified
How do I fix the below so I don't get this error?
SELECT dbo.PS_Proj.[Project ID],
case
when PS_Proj.[City Name] is not null then concat(PS_Proj.[City Name], ' ', PS_Proj.[State])
when PS_Billing.[Location] is not null then max(PS_Billing.[Location])
when PS_Time.[Labor Location ID] is not null then max(PS_Location.[Labor Location Name])
else null
end AS [Location]
FROM dbo.PS_Location RIGHT OUTER JOIN
dbo.PS_Time ON dbo.PS_Location.[Labor Location ID] = dbo.PS_Time.[Labor Location ID] RIGHT OUTER JOIN
dbo.PS_Proj ON dbo.PS_Time.[Project ID] = dbo.PS_Proj.[Project ID] LEFT OUTER JOIN
dbo.PS_Billing ON dbo.PS_Proj.[Project ID] = dbo.PS_Billing.[Project ID]
ORDER BY PS_Billing.[T/S Date], PS_Time.[Date]
I'd like for the most recent PS_Billing location to show and if that is null for the most recent PS_Time location to show.
Create your view without Order By. Remove ORDER BY PS_Billing.[T/S Date], PS_Time.[Date] And add them to your SELECT.
SELECT
PS_Billing.[T/S Date] AS TsDate,
PS_Time.[Date] AS Date,
dbo.PS_Proj.[Project ID],
case
when PS_Proj.[City Name] is not null then concat(PS_Proj.[City Name], ' ', PS_Proj.[State])
when PS_Billing.[Location] is not null then max(PS_Billing.[Location])
when PS_Time.[Labor Location ID] is not null then max(PS_Location.[Labor Location Name])
else null
end AS [Location]
FROM dbo.PS_Location RIGHT OUTER JOIN
dbo.PS_Time ON dbo.PS_Location.[Labor Location ID] = dbo.PS_Time.[Labor Location ID] RIGHT OUTER JOIN
dbo.PS_Proj ON dbo.PS_Time.[Project ID] = dbo.PS_Proj.[Project ID] LEFT OUTER JOIN
dbo.PS_Billing ON dbo.PS_Proj.[Project ID] = dbo.PS_Billing.[Project ID]
And select from your view with order by line
Select FROM YOUR_VIEW_NAME as V
Order By V.TsDate, V.Date
You have some aggregate data inside your case expression and you don't have a group by. I am making some guesses here. Also, you should get in the habit of using aliases, it makes things a lot simpler. I would also suggest not putting spaces in your column names as it forces you to constantly wrap columns in square brackets.
Something like this should get you close.
SELECT p.[Project ID]
, MAX(case
when p.[City Name] is not null then concat(p.[City Name], ' ', p.[State])
when b.[Location] is not null then b.[Location]
when t.[Labor Location ID] is not null then l.[Labor Location Name]
else null
end) AS [Location]
FROM dbo.PS_Location l
RIGHT OUTER JOIN dbo.PS_Time t ON l.[Labor Location ID] = t.[Labor Location ID]
RIGHT OUTER JOIN dbo.PS_Proj p ON t.[Project ID] = p.[Project ID]
LEFT OUTER JOIN dbo.PS_Billing b ON p.[Project ID] = b.[Project ID]
GROUP BY p.[Project ID]

SQL replace int in string by text

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')

How to join a sub-query to

Hey guys I have this report that i am working on. It has multiple Columns and in between those columns are some Left joins. so my question is, how do i add a left join to the query?
Declare #asofdate smalldatetime
Set #asofdate = '2017-08-24'
SELECT
OCCONR as [Company Number],
OCCMNR as [Claim Number], --CMOCUR db)
OCEXCD as [Claim Counsel], ---(CMOCUR db)
DATEFROMPARTS(OCEFCN*100+OCEFYY,OCEFMM,OCEFDD) as [Policy Effective Date], -- (CMOCUR db)
iif([True CAT Nbr] is null, OCCTCD, [True CAT Nbr]) as [CAT Code], ---(Check Comment 1)
iif(LSCMNT is null,'', LSCMNT) as [NOA Comments], --- (Check Comemnt 2)
concat([First_Name],' ',[Last_Name]) as [Insured Name], --- (Check Comment 3)
DatefromParts([OCLSCN]*100+[OCLSYY],[OCLSMM],[OCLSDD]) as [Occurrence Date], --- (CMOCUR db)
rtrim(ltrim(OCDACC)) as [Cause of Loss], --- (CMOCUR db)
DatefromParts([OCRPCN]*100+[OCRPYY],[OCRPMM],[OCRPDD]) as [Claim Reported Date], --- (CMOCUR db)
iif(LSSETLD is null,'', LSSETLD) as [Settled Indicator], --- (Check Comment 2)
--iif(SUM([Incurred Loss NET OF S&S]) - SUM([Paid Loss NET OF S&S]) = 0, 'Closed', 'Open') as [Status in AS-400]
iif(OCCLCN=0,'',datefromparts(OCCLCN*100+OCCLYY,OCCLMM,OCCLDD)) as [Closed Date], --- (CMOCUR db)
iif(LSCLCN=0 OR LSCLCN IS NULL,'',DatefromParts(LSCLCN*100+LSCLYY,LSCLMM,LSCLDD)) as [All Closed Date] ----(Comment 2)
--[Last Reserve Change Date]
FROM AS400.FRTDTA250.CMOCUR
LEFT JOIN Lookups.dbo.[Bad CAT Codes] ON [Claim Nbr] = OCCMNR ---- This LEFT JOIN provides the CAT CODE for this report (Comment 1)
LEFT JOIN AS400.FRTDTA250.CMLSCP ON LSCMNR = OCCMNR ---- This is used to pull any COMMENTS and SETTLEMENT made on a claim (Comment 2)
LEFT JOIN Lookups.dbo.Insured_Name_By_PolicyNum ON Prefix = OCPRFX and Polnum = OCPLNR --- This is to add the INSURED NAME (comment 3)
So, the issue i am having is that i have this other sub-queries that are meant to provide information for the [Status in AS-400] and [Last Reserve Change Date]. How do i connect this queries to the SQL?
Below are the 2 queries that i am trying to add to the select query:
-- Query for [Status in AS-400]
SELECT
---s1.[Claim Number],
iif(SUM(s1.[Incurred Loss NET OF S&S]) - SUM(s1.[Paid Loss NET OF S&S]) = 0, 'Closed', 'Open') as [Open / Closed]
---SUM(s1.[Incurred Loss NET OF S&S]) - SUM(s1.[Paid Loss NET OF S&S]) as [Loss C/R]
FROM
(
SELECT
OCCMNR as [Claim Number],
SUM(iif(DATASETTYPE IN ('Incurred LOSS'), CTTRAM, iif(DATASETTYPE IN ('SALVAGE','SUBROGATION','OTHER RECOVERIES'), -CTTRAM, 0))) AS [Incurred Loss NET OF S&S],
SUM(iif(DATASETTYPE IN ('Paid LOSS'), CTTRAM, iif(DATASETTYPE IN ('SALVAGE','SUBROGATION','OTHER RECOVERIES'), -CTTRAM, 0))) AS [Paid Loss NET OF S&S]
FROM AS400.FRTDTA250.[CMOCUR] AS A
INNER JOIN AS400.FRTDTA250.[CMTRAN]AS B ON A.OCCMNR = B.CTCMNR
LEFT JOIN Lookups.dbo.TransactionCodes AS C ON B.CTGRPC = C.TransactionCode
WHERE DATEFROMPARTS(CTTRCN*100+CTTRYY, CTTRMM, CTTRDD) <= #asofdate
and CTTRSB not in (4,12)
and CTTSCD = 'P'
GROUP BY OCCMNR
) as s1
GROUP BY s1.[Claim Number]
ORDER BY s1.[Claim Number]
--Query for [Last Reserve Change Date]
Select [Claim Number],
left(convert(CHAR, Max([Loss Transaction Date]), 120),10) as [Last Reserve Change Date]
From
(
Select [OCCMNR] as [Claim Number],
DATEFROMPARTS(CTTRCN*100+CTTRYY, CTTRMM, CTTRDD) as [Loss Transaction Date],
iif(DATASETTYPE IN ('Incurred LOSS'), CTTRAM, 0) as [Incurred Loss]
From AS400.FRTDTA250.[CMTRAN] as b1
LEFT JOIN AS400.FRTDTA250.[CMOCUR] as a1
ON a1.OCCMNR = b1.CTCMNR
LEFT JOIN Lookups.dbo.TransactionCodes as c1
ON b1.CTGRPC = c1.TransactionCode
Where (iif(DATASETTYPE IN ('Incurred LOSS'), CTTRAM, 0) <> 0)
and DATEFROMPARTS(CTTRCN*100+CTTRYY, CTTRMM, CTTRDD) <= #asofdate
and CTTRSB not in (4,12)
AND CTTSCD = 'P'
) s2
group by [Claim Number]
) as G
on G.[Claim Number] = a.[OCCMNR]
And i use a MS-SQL Server
Format for joining Sub-queries are as follows:
SELECT *
FROM TABLEA A
INNER JOIN TABLED D on A.ID = D.ID
LEFT JOIN
( SELECT B.ID,COLUMN_A
FROM TABLEB B
INNER JOIN TABLEC C ON B.ID = C.ID
) X ON A.ID = X.ID

BETWEEN condition is not working when using NOT IN

SELECT *
FROM Customer
INNER JOIN Ledger Entry on [No_] = [Customer No_]
WHERE No_ NOT IN ([Posting Date] between '2013-10-01' and '2013-10-31')
the BETWEEN condition is not working.
This is not how not in works, you are comparing No_ which seems to be Id of customer with Posting Date so this should fail.
I think you wanted something like that:
SELECT *
FROM Customer c
inner join [Ledger Entry] le on c.[No_] = le.[Customer No_]
where c.[No_] not in (
select l.[Customer No_]
from [Ledger Entry] l
where l.[Posting Date] between '2013-10-01' and '2013-10-31'
)
but for such query it should be simplified to:
SELECT *
FROM
Customer c
inner join [Ledger Entry] le on c.[No_] = le.[Customer No_]
where le.[Posting Date] < '2013-10-01' or le.[Posting Date] > '2013-10-31'
without using not in and between at all
Firstly, your date should be compared to another date type column.
Secondly, according to Aaron Bertrand, you should refrain from using BETWEEN for dates, you can go through the article to know that he's right.
So intead, I'd suggest you to proceed as;
SELECT * FROM Customer
inner join LedgerEntry
on Customer.[No_] = LedgerEntry.[Customer No_]
where LedgerEntry.[Posting Date] < '2013-10-01' and LedgerEntry.[Posting Date] > '2013-10-31'