SQL Query for Access Pie chart - Group By one field but group certain values - sql

Trying to automatically produce a piechart in access which will show me 3 values (completed, pending and queued)
However in my status field I have several values for pending (sent, monitoringStage1, monitoringStage2, finalApproval)
My query at present gives me the count of each item individually:
SELECT Status, Count(*) AS [Count]
FROM StatusTable
GROUP BY Status
ORDER BY Status;
How would I edit it to count sent, monitoringStage1, monitoringStage2, and finalApproval as one item called pending?
Also on a side note, does anybody know how to put a line at a certain point on a piechart by percentage? So in the piechart created I could have a line to indicate the target number of completed items to compare against current progress.

You can't use CASE in a query, only in VBA.
This will take care of it:
SELECT qryTestx.ThisStatus, Count(qryTestx.Status) AS CountOfStatus
FROM (SELECT (IIf([StatusTable.Status] in ("sent","monitoringStage1","monitoringStage2","finalApproval"),"Pending",[StatusTable.Status])) AS ThisStatus, StatusTable.Status
FROM StatusTable) qryTestx
GROUP BY qryTestx.ThisStatus;

Try this and don't forget to vote ;)
select
count(*),
case
when Status in ( 'sent', 'monitoringStage1', 'monitoringStage2', 'finalApproval') then 'pending'
else status
end as status
from StatusTable
group by
case
when Status in ( 'sent', 'monitoringStage1', 'monitoringStage2', 'finalApproval') then 'pending'
else status
end

Related

SQL select column group by where the ratio of a value is 1

I am using PSQL.
I have a table with a few columns, one column is event that can have 4 different values - X1, X2, Y1, Y2. I have another column that is the name of the service and I want to group by using this column.
My goal is to make a query that take an event and verify that for a specific service name I have count(X1) == count(X2) if not display a new column with "error"
Is this even possible? I am kinda new to SQL and not sure how to write this.
So far I tried something like this
select
service_name, event, count(service_name)
from
service_table st
group by
(service_name, event);
I am getting the count of each event for specific service_name but I would like to verify that count of event 1 == count of event 2 for each service_name.
I want to add that each service_name have a choice of 2 different event only.
You may not need a subquery/CTE for this, but it will work (and makes the logic easier to follow):
WITH event_counts_by_service AS (SELECT
service_name
, COUNT(CASE WHEN event='X1' THEN 1 END) AS count_x1
, COUNT(CASE WHEN event='X2' THEN 1 END) AS count_x2
FROM service_table
GROUP BY service_name)
SELECT service_name
, CASE WHEN count_x1=count_x2 THEN NULL ELSE 'Error' END AS are_counts_equal
FROM event_counts_by_service

Build query that brings only sessions that have only errors?

I have a table with sessions events names. Each session can have 3 different types of events.
There are sessions that have only error type event and I need to identify them by getting a list those session.
I tried the following code:
SELECT
test.SessionId, SS.RequestId
FROM
(SELECT DISTINCT
SSE.SessionId,
SSE.type,
COUNT(SSE.SessionId) OVER (ORDER BY SSE.SessionId, SSE.type) AS total_XSESIONID_TYPE,
COUNT(SSE.SessionId) OVER (ORDER BY SSE.SessionId) AS total_XSESIONID
FROM
[CMstg].SessionEvents SSE
-- WHERE SSE.SessionId IN ('fa3ed523-60f9-4af0-a85f-1dec9e9d2cdb' )
) AS test
WHERE
test.total_XSESIONID_TYPE = test.total_XSESIONID
AND test.type = 'Errors'
-- AND test.SessionId IN ('fa3ed523-60f9-4af0-a85f-1dec9e9d2cdb' )
Each session can have more than one type, and I need to count only the sessions that have only type 'errors'. I don't want to include sessions that have additional types of events in the count
While I'm running the first query I'm getting a count of 3 error event per session, but while running the all procedure the number is multiplied to 90?
Sample table :
sessionID
type
fa3ed523-60f9-4af0-a85f-1dec9e9d2cdb
Errors
fa3ed523-60f9-4af0-a85f-1dec9e9d2cdb
Errors
fa3ed523-60f9-4af0-a85f-1dec9e9d2cdb
Errors
00c896a0-dccc-41bf-8dff-a5cd6856bb76
NonError
00c896a0-dccc-41bf-8dff-a5cd6856bb76
Errors
00c896a0-dccc-41bf-8dff-a5cd6856bb76
Errors
00c896a0-dccc-41bf-8dff-a5cd6856bb76
Errors
In this case I should get
sessionid = fa3ed523-60f9-4af0-a85f-1dec9e9d2cdb
Please advice - hope this is clearer now, thanks!
It's been a long time but I think something like this should get you the desired results:
SELECT securemeSessionId
FROM <TableName> -- replace with actual table name
GROUP BY securemeSessionId
HAVING COUNT(*) = COUNT(CASE WHEN type = 'errors' THEN 1 END)
And a pro tip: When asking sql-server questions, it's best to follow these guidelines
SELECT *
FROM NameOfDataBase
WHERE type!= 'errors'
Is it what you wanted to do?

Find duplicates using parcel number and updated their status. SQL Server 2014

I have a problem with duplicate records in a SQL Server 2014 database.
Users get a small postcard with a parcel number printed on them.
The postcard also shows a link to a simple form that they can use, to register their parcel.
The form unfortunately does not have any type of validation, to ensure that the same parcel does not get submitted more than once.
I currently have no control on the web form, and I am not sure how long will take for the responsible team to implement validation on it.
So I have to come up with a routine to deactivate the duplicate records, and keep only one.
This has to be a query that process a bulk of records, no tokens passed to the routine.
When the web form gets submitted, it creates a record id in sequential order, and assigns an application status of "Registered'.
I think that the way to correct this, would be to take highest record id value per parcel, and that would be the one to keep, the rest, will have to be deactivated.
Deactivate the non most recent records putting a rec_status of "I"
Set APPLICATION_STATUS to 'Closed' to the non most recent records
The query I use, returns 4 columns: Record Id, Parcel Number, Record Status, and Application Status
SELECT
B.[RECORD_ID],
B.[PARCEL_NBR],
B.[RECORD_STATUS], -- The value of this column would be "I" for the duplicate records.
B.[APPLICATION_STATUS]
FROM
A_TABLE A
INNER JOIN B_TABLE B
ON A.PARCEL_NBR = B.PARCEL_NBR
AND (A.APPLICATION_STATUS IS NULL
OR B.APPLICATION_STATUS = 'Registered');
Initial Output:
RECORD_ID PARCEL_NBR RECORD_STATUS APPLICATION_STATUS
REC-00081 0608012098 A Registered
REC-00082 0608012098 A Registered
REC-00083 0608012098 A Registered
Expected Output:
RECORD_ID PARCEL_NBR RECORD_STATUS APPLICATION_STATUS
REC-00081 0608012098 I Closed - this record got updated
REC-00082 0608012098 I Closed - this record got updated
REC-00083 0608012098 A Registered
I think that perhaps a cursor might be part of the solution? Honestly I am not sure. I kindly ask for your help.
You can use window functions and case logic:
SELECT B.[RECORD_ID], B.[PARCEL_NBR],
(CASE WHEN ROW_NUMBER() OVER (PARTITION BY B.PARCEL_NBR ORDER BY B.RECORD_ID DESC) > 1
THEN 'I' ELSE B.[RECORD_STATUS]
END) as RECORD_STATUS,
(CASE WHEN ROW_NUMBER() OVER (PARTITION BY B.PARCEL_NBR ORDER BY B.RECORD_ID DESC) > 1
THEN Closed - this record got updated ELSE B.APPLICATION_STATUS
END) as APPLICATION_STATUS,
B.[]
FROM A_TABLE A JOIN
B_TABLE B
ON A.PARCEL_NBR = B.PARCEL_NBR AND
(A.APPLICATION_STATUS IS NULL OR B.APPLICATION_STATUS = 'Registered');
I'm not sure what role A_TABLE plays in this, but this may give you what you want:
update B_TABLE
set record_Status = 'I'
, application_status = 'Closed - this record got updated'
where record_status = 'A'
and application_status = 'Registered'
and record_id <> (select max(record_id)
from B_TABLE b
where b.parcel_nbr = B_TABLE.parcel_nbr
and b.record_status = 'A'
and b.application_status = 'Registered');

How can I use postgresql to sort a query with a custom sort order on a string?

I have a table incident that has a status that is a string.
I want to query all incidents with a custom sort order.
A status can be one of the following: inProgress, completed, canceled
I want to be able to have a sort that is custom. Let the client specify the sort order. I am having problems with the query itself though.
I've tried a few things:
SELECT *
FROM incident as i
ORDER BY array_position(array["inProgress", "completed", "canceled"], i.status)
SELECT *
FROM incident as i
ORDER BY case when status = "inProgress" then 0
case when status = "completed" then 1
case when status = "canceled" then 2
else 3
I get the error Unhandled rejection SequelizeDatabaseError: column "inProgress" does not exist on all of my attempts.
I'm expecting inProgress to be a value of status, but I'm not sure what I'm doing wrong.
Check documentation for the right sintaxis. And text use single quotes. Double quotes is for fieldnames
ORDER BY case
when status = 'inProgress' then 0
when status = 'completed' then 1
when status = 'canceled' then 2
else 3
end

SQLServer Creating a Case in a query based on top 100 results

I'm trying to create a SQL Server query based on the following criteria:
The query focuses on three columns: Report_Status, Error_Message, and Create_Date. The purpose of the query is to filter the top 100 most recent results based on the Create_Date. Once that's done, it needs to see if EVERY row in Report_Status in that top 100 says 'Failed' AND that Error_Message does not contain 'Placement is missing%'.
If it meets those conditions, then it needs to output the message "Potential service failure." If it doesn't meet those conditions, then it either needs to do nothing or output something normal, like "No problems found."
I figured a Case might be the best way to do this, so I tried it out. I'm having trouble getting it to work, though:
select Report_Status, Error_Message, Create_Date,
case
when Report_Status = 'Failed' and Error_Message not like 'Placement is missing%' then 'Potential service failure.'
ELSE 'No problems found.'
end
from [AUDIT_TABLE] limit 100
Is this the best way to approach this problem? If so, what do I need to change so this works? If it's not a good way, what's a better way to tackle the problem?
You would appear to want something like this:
select (case when count(*) = 100 then 'Potential service failure.'
else 'No problems found.'
end) as summary
from (select a.*
from [AUDIT_TABLE]
order by date desc
fetch first 100 rows only
) t100
where Report_Status = 'Failed' and
Error_Message not like 'Placement is missing%'
I ended up working with a coworker to solve this. Gordon Linoff's CASE section was great, but we changed how we searched for the most recent 100 records by also using the Report_ID field.
select
(case when count(*) = 100 then 'Potential failure.'
else 'No problems found.'
end) as Result
from Audit_Table
where Report_Status = 'fail'
and Error_Message not like 'Placement is missing%'
and Report_ID >= (select min(Report_ID) from (select top 100 * from Audit_Table order by Report_ID desc ) t100)