SQL Server 2008 query not executing properly - sql

I have to run this query on my SQL Server 2008.
I need to join the 2 tables (Gasper_object and Ticket) and get the results where Gasper_object.id is also shown.
SELECT
TICKET.ACTION_CODE_KEY,
TICKET.OBJECT_KEY,
GASPER_OBJECT.ID,
CASE
WHEN ACTION_CODE_KEY IN (4,8) THEN 'OUT OF SERVICE'
WHEN ACTION_CODE_KEY IS NULL THEN 'IN SERVICE'
ELSE 'FAULTY SERVICE'
END "STATUS"
FROM
TICKET
INNER JOIN
GASPER_OBJECT ON ticket.OBJECT_KEY = GASPER_OBJECT.OBJECT_KEY
GROUP BY
ticket.object_key, GASPER_OBJECT.ID;
What should I do ?
UPDATE
This is what I received as a task to complete
IF THE ACTION_CODE IS 4 OR 8, THE COLOUMN NAME SHOULD BE OUT OF SERVICE
OTHERWISE IT SHOULD BE FAULTY SERVICE
IF THE OBJECT HAS NO TICKET AT ALL THEN IT'S IN SERVICE
GASPER_OBJECT.ID, STATUS SHOULD BE THE OUTPUT COLUMNS AFTER QUERYING
IF THE OBJECT HAS MORE THAN ONE TICKET WHICH APPLIES TO THE CRITERIA, USE DISTINCT

Just add rest of the columns to the group by.
SELECT
TICKET.ACTION_CODE_KEY,
TICKET.OBJECT_KEY,
GASPER_OBJECT.ID,
CASE
WHEN ACTION_CODE_KEY IN (4,8) THEN 'OUT OF SERVICE'
WHEN ACTION_CODE_KEY IS NULL THEN 'IN SERVICE'
ELSE 'FAULTY SERVICE'
END "STATUS"
FROM
TICKET
INNER JOIN
GASPER_OBJECT ON ticket.OBJECT_KEY = GASPER_OBJECT.OBJECT_KEY
GROUP BY
TICKET.ACTION_CODE_KEY, ticket.object_key, GASPER_OBJECT.ID;

In an aggregation query, all the columns not in the group by need to be arguments to aggregation functions. Here is an example of query that should at least run:
SELECT t.object_key, o.ID,
(CASE WHEN MAX(ACTION_CODE_KEY) IN (4, 8) THEN 'OUT OF SERVICE'
WHEN MAX(ACTION_CODE_KEY) IS NULL THEN 'IN SERVICE'
ELSE 'FAULTY SERVICE'
END) as STATUS
FROM TICKET t inner join
GASPER_OBJECT o
on t.OBJECT_KEY = o.OBJECT_KEY
group by t.object_key, o.ID;
Your question doesn't explain what you want to do, so this may or may not produce the results you expect.

Related

Troubleshooting Conditional Grouping with CASE (SQL Server 2008)

I'm hoping that someone is willing to help. I'm new to SQL and struggling to get a simple query debugged.
I want to create a simple frequency table to see how many values are missing (i.e. = 00000000) for the ArrestDate field.
SELECT
CASE WHEN ArrestDate=00000000 THEN 'NO DATE' ELSE 'HAS DATE' END AS HasDate,
CASE WHEN ArrestDate=00000000 THEN 0 ELSE 1 END as nDate
FROM ARREST_INFO
--GROUP BY HasDate
--GROUP BY CASE WHEN ArrestDate=00000000 THEN 'NO DATE' ELSE 'HAS DATE' END
Lines 1-4 parse without errors (output below).
Line 5 returns: Invalid column name 'HasDate'.
Line 6 returns: 'ARREST_INFO.ArrestDate' is invalid in the select
list because it is not contained in either an aggregate function or
the GROUP BY clause.
Since lines 1-4 run properly, I tried wrapping them inside another SELECT statement but this also elicits an error ("Invalid column name 'HasDate'.")
SELECT * FROM (
SELECT
CASE WHEN ArrestDate=00000000 THEN 'NO DATE' ELSE 'HAS DATE' END AS HasDate,
CASE WHEN ArrestDate=00000000 THEN 0 ELSE 1 END as nDate
FROM ARREST_INFO
)
GROUP BY HasDate
--GROUP BY CASE WHEN ArrestDate=00000000 THEN 'NO DATE' ELSE 'HAS DATE' END
Sadly, I can't update the SQL Server version. I'd be very grateful for any insight!
This answer to a previous question helped me figure out at least part of my problem. My Select statement referred to 2 columns, (nDate and HasDate), but my Group By statement only referred to one of them, so SQL didn't have enough information to determine how to display the unaggregated column data.
#Bill Karwin wrote:
https://stackoverflow.com/a/13999903/9499084
This demonstrates the single-value rule, which prohibits the undefined results you get when you run a GROUP BY query, and you include any columns in the select-list that are neither part of the grouping criteria, nor appear in aggregate functions (SUM, MIN, MAX, etc.).
I'm still not sure why SQL doesn't recognize the new column defined in the Select statement (HasDate) when it's redeployed in the Group By statement, but at least I have functioning code now -- see screenshot below for results.
Here's my updated code:
SELECT
CASE WHEN ArrestDate=00000000 THEN 'NO DATE' ELSE 'HAS DATE' END AS HasDate,
SUM(CASE WHEN ArrestDate=00000000 THEN 0 ELSE 1 END) AS nDate,
COUNT(*) as TotalCases
FROM ARREST_INFO
GROUP BY CASE WHEN ArrestDate=00000000 THEN 'NO DATE' ELSE 'HAS DATE' END
enter image description here

SQL Group by CASE result

I have a simple SQL query on IBM DB2. I'm trying to run something as below:
select case when a.custID = 42285 then 'Credit' when a.unitID <> '' then 'Sales' when a.unitID = '' then 'Refund'
else a.unitID end TYPE, sum(a.value) as Total from transactions a
group by a.custID, a.unitID
This query runs, however I have a problem with group by a.custID - I'd prefer not to have this, but the query won't run unless it's present. I'd want to run the group by function based on the result of the CASE function, not the condition pool behind it. So, I'm looking something like:
group by TYPE
However adding group by TYPE reports an error message "Column or global variable TYPE not found". Also removing a.custID from group section reports "Column custID or expression in SELECT list not valid"
Is this going to be possible at all or do I need to review my CASE function and avoid using the custID column since at the moment I'm getting a grouping also based on custID column, even though it's not present in SELECT.
I understand why the grouping works as it does, I'm just wondering if it's possible to get rid of the custID grouping, but still maintain it within CASE function.
If you want terseness of code, you could use a subquery here:
SELECT TYPE, SUM(value) AS Total
FROM
(
SELECT CASE WHEN a.custID = 42285 THEN 'Credit'
WHEN a.unitID <> '' THEN 'Sales'
WHEN a.unitID = '' THEN 'Refund'
ELSE a.unitID END TYPE,
value
FROM transactions a
) t
GROUP BY TYPE;
The alternative to this would be to just repeat the CASE expression in the GROUP BY clause, which is ugly, but should still work. Note that some databases (e.g. MySQL) have overloaded GROUP BY and do allow aliases to be used in at least some cases.

Converting SQL pivot table to T-SQL for Report Builder 3.0

I've been having a spot of bother importing a rather long-winded SQL pivot table dataset into SQL Server Report Builder 3.0 in a format which allows me to add parameter to the report outcome. I understand that this requires the query to be T-SQL friendly
The context is, in case it helps, is that i'm building a report to give a view over various market research panel's eligibility statuses, and i'd like to be able to present a drop down menu to let users flick between panels. So the end #parameter will be on PanelCode / PanelName. It's a composite query:
SELECT
ELT.PanelCode,
ELR.PanelName,
ELR.Year,
ELT.PeriodType,
ELT.PeriodValue,
ELT.TotalPanelists,
ELT.EligiblePanelists,
ELR.TotalEligible,
ELR.TotalVacation,
ELR.TotalExcused,
ELR.TotalInactive,
ELR.TotalConnection,
ELR.TotalCompliance
FROM --the Ineligibility Reason Pivot Table (ELR)
(SELECT
PanelCode,
PanelName,
Year,
PeriodType,
PeriodValue,
Max([Eligible]) as TotalEligible,
Max([Vacation]) as TotalVacation,
Max([Excuse]) as TotalExcused,
Max([Inactive]) as TotalInactive,
Max([Connection]) as TotalConnection,
Max([Compliance]) as TotalCompliance
FROM
(SELECT
PanelCode,
PanelName,
Year,
PeriodType,
PeriodValue,
EligibilityFailureReason,
FROM FullPanellistEligibilityView) FPR
Pivot
(count(EligibilityFailureReason) FOR EligibilityFailureReason IN ([Eligible], [Vacation], [Excuse], [Inactive], [Connection], [Compliance])) AS PVT
WHERE PeriodType <> '4 week period' and Year > 2012
GROUP BY PanelCode, PanelName, PeriodType, Year, PeriodValue) as ELR
, -- And the Eligibility Totals Query, ELT
(
SELECT
PanelCode,
PanelName,
Year,
PeriodType,
PeriodValue,
Count(Poll1s) as TotalPanelists,
Sum(Poll1s) as EligiblePanelists
FROM
(SELECT
PanelCode,
PanelName,
Year
PeriodType,
PeriodValue,
CAST(isEligible as INT) as Poll1s
FROM FullPanellistEligibilityView) FPR
GROUP BY PanelCode, PeriodType, PeriodValue) ELT
WHERE (ELT.PeriodValue=ELR.PeriodValue) and (ELT.PanelCode=ELR.PanelCode)
I've been really struggling to find resources online which suggest how to take larger queries and make them Parameter-able in Report Builder 3. What do I need to add in addition to WHERE PanelName = #PanelName to make this run?
EDIT1: I don't doubt that I've made this query far more complicated than necessary, i'm self-teaching. The schema isn't really necessary as all this data is pulled from one single, already existing view, FullPanellistEligibilityView, sample data, stripped down and mocked up from the view, can be found here
There are two things you need to do in order to set up a data driven parameter selection.
Firstly, you need to create a dataset to populate your parameter drop down menu. This needs to list all the values you want your user to be able to select, in the correct order. This can return a column each for the Label shown to the user and the value passed to the query:
select distinct PanelCode -- Parameter Value
,PanelName -- Parameter Label
from FullPanellistEligibilityView
order by PanelName
Create a Parameter and set the available values to this dataset, with the appropriate column used for the Label and Value properties.
Secondly, you need to add a filter to your dataset. I have taken the liberty of re-writing your query above to use a derived table/common table expression/cte instead of your PIVOT. The code below includes the reference to the SSRS parameter which will insert the 'Value' for the parameter once selected. This code is obviously not tested as I don't have your schema, but the design should be easy enough to understand:
with t
as
(
select PanelCode
,PeriodValue
,count(isEligible) as TotalPanelists -- I'm assuming this is a BIT column, in which case it shouldn't have any null values. If it does, you will need to handle this with count(isnull(isEligible,0))
,Sum(CAST(isEligible as INT)) as EligiblePanelists
from FullPanellistEligibilityView
where PanelCode = #PanelCode -- This will filter your data due to the INNER JOIN below.
group by PanelCode
,PeriodType
,PeriodValue
)
select e.PanelCode
,e.PanelName
,e.Year
,e.PeriodType
,e.PeriodValue
,t.TotalPanelists
,t.EligiblePanelists
,sum(case when e.EligibilityFailureReason = 'Eligible' then 1 else 0 end) as TotalEligible,
,sum(case when e.EligibilityFailureReason = 'Vacation' then 1 else 0 end) as TotalVacation,
,sum(case when e.EligibilityFailureReason = 'Excuse' then 1 else 0 end) as TotalExcused,
,sum(case when e.EligibilityFailureReason = 'Inactive' then 1 else 0 end) as TotalInactive,
,sum(case when e.EligibilityFailureReason = 'Connection' then 1 else 0 end) as TotalConnection,
,sum(case when e.EligibilityFailureReason = 'Compliance' then 1 else 0 end) as TotalCompliance
from FullPanellistEligibilityView e
inner join t
on(e.PanelCode = t.PanelValue
and e.PeriodValue = t.PeriodValue
)
where e.PeriodType <> '4 week period'
and e.Year > 2012
group by e.PanelCode
,e.PanelName
,e.Year
,e.PeriodType
,e.PeriodValue
,t.TotalPanelists
,t.EligiblePanelists

SQL Server 2008 Sum function not returning rows with no data

I'm trying to write a report that is the product of two tables. In short, there is an Office table and a Report table. I want to return all offices, regardless if there are any reports, and a sum of the line counts from the Reports table.
My report looks like the following:
SELECT
o.NAME,
SUM(rpt.transcriptionlinecount) AS 'Total Lines'
FROM
office AS o
LEFT JOIN
RptLineCountInfo AS rpt ON rpt.officeID = o.officeID
WHERE
rpt.finishedTime BETWEEN startDate AND endDate + 1
AND rpt.officeID = CASE
WHEN officeID IS NULL THEN rpt.officeID
ELSE officeID
END
AND (rpt.dictationStatus != 'd'
AND rpt.dictationstatus != 'q')
AND rpt.officeID != '2'
OR rpt.transcriptionLineCount IS NULL
GROUP BY
o.[name]
ORDER BY
o.[name];
I do have some additional information in the where clause, such as report status and date range. The issue I have is that if I query the Office table, there should are 250 results. With my query above only 101 results are returned. There were zero reports for the remaining 149 offices during this time frame, but I would still like them to appear on the report either with a 0 or a Null. Any suggestions on on how to achieve this would be great.

Distinct in SQL Server

I am executing the following query,
Select distinct
a.cr_id,
Case
When ca.ca_vote = 'Approve' and ca.ca_title='MANAGER' Then ca.ca_email
When ca.ca_vote = 'Reject' Then ''
When ca.ca_vote = 'Pending' Then ''
When ca.ca_vote = 'IN PROCESS' Then ''
End as ca_email
from
credit a
inner join credit_approvals ca on ca.c_id=a.cr_id
where
a.cr_cs_date between Convert(varchar(20),'11/16/2011',101) and dateadd(day,1,convert (varchar(20),'11/16/2011',101))
order by
a.cr_id
Despite distinct for cr_id, it is still displaying the duplicate values. Please let me know how to handle this, so that I could able to display only distinct records.
Distinct is applied to all columns, not the one which is immediately after Distinct.
If you have several different ca_email for a cr_id, you will see them all.
If you don't want that, you have to come up with a rule to decide what record among the duplicates must stay.