How do I group results in columns using case statements? - sql-server

I want to group the results in a separate column as Idle Total, Lock Total etc. I'm not a programmer and certainly not an db admin so i may not have all tools and access but I'll appreciate any help.
I've tried using other methods, here and other websites but it always comes down to the SUM or GROUP BY functions which I understand very little of.
SELECT TOP 10000
AGENT.AGENT_NAME,
ID.AGENT_ID,
TIME.DURATION_SECONDS,
SUM(CASE
WHEN ID.AGENT_ID IN ('IDLE','LOCK','LOGIN')
THEN 'WORKSTATE'
ELSE NULL
END)
FROM
WORKSTATE TIME
LEFT JOIN
DATABASE ID ON ID.INDEX = TIME.AGENT_INDEX
LEFT JOIN
DATABASE ORG ON TIME.AGENT_LOGIN_ID = ORG.AGENT_NAME
WHERE
(TIME.START_TIME = 2019-08-19) AND ORG.TEAM IN 'COMPANY'
GROUP BY
AGENT_AGENT_NAME,
ID.AGENT_ID,
TIME.DURATION_SECONDS
I would like the results to group TOTAL time an agent was Idle, Locked or Login on a given date.
Date Name Idle hrs Lock hrs Login
--- --- ------ ------ -----
08/19 John 2.3 1.7 4

You need to add CASE expression for each column, following query would help you to start with:
SELECT
TIME.START_TIME,
TIME.AGENT_LOGIN_ID,
SUM(CASE
WHEN ID.AGENT_ID = 'IDLE'
THEN TIME.DURATION_SECONDS END) as IdleTime, -- You may calculate You can formula to get HOURS from SECONDS or replace the column "DURATION_SECONDS" with the one that you looking to do aggregation
SUM(CASE
WHEN ID.AGENT_ID = 'LOCK'
THEN TIME.DURATION_SECONDS END) as LockTime,
SUM(CASE
WHEN ID.AGENT_ID = 'LOGIN'
THEN TIME.DURATION_SECONDS END) as LogTime
FROM WORKSTATE TIME
LEFT JOIN
DATABASE ID ON TIME.AGENT_INDEX = ID.INDEX
LEFT JOIN
DATABASE ORG ON TIME.AGENT_LOGIN_ID = ORG.AGENT_NAME
WHERE
(TIME.START_TIME = 2019-08-19) AND ORG.TEAM = 'COMPANY'
GROUP BY
TIME.START_TIME, TIME.AGENT_LOGIN_ID,

Related

Pivot Values as Column Headers

I have some questions in a table named GeneralReviews_Questions q that I want to use as column headers rather than values. I'm accomplishing this now by sticking the question responses into a #temp table and then joining a second query to get the responses and hard-coding the questions as column names. It works but it's a maintenance nightmare. How do I accomplish this without hard-coding the questions as column names?
SELECT
r.ReviewID,
max(case when q.Sequence = 1 AND q.Category = 'General' AND q.Active = 1 then Response end)
AS [Q1],
max(case when q.Sequence = 2 AND q.Category = 'General' AND q.Active = 1 then Response end)
AS [Q2]
INTO #temp
FROM
GeneralReviews gr INNER JOIN GeneralReviews_Questions_Responses r
ON gr.ReviewID = r.ReviewID INNER JOIN
GeneralReviews_Questions q ON r.QuestionID = q.QuestionID
GROUP BY
r.ReviewID;
SELECT
#temp.ReviewID AS ReviewID
,#temp.[Q1] AS [Q1 For the past four quarters, were the Quarterly Interest Statements sent
if the account and loan type/status required it?]
,#temp.[Q2] AS [Q2 We will focus on 1-2 events (repay plan change, new disbursement, end of
a defer/forb, acct adjustment etc) per qtr?]
FROM
GeneralReviews gr INNER JOIN
#temp ON gr.ReviewID = #temp.ReviewID
Desired Results: https://i.stack.imgur.com/HPnS3.jpg

Joomla long slow queries resulting in 503 Error

Currently I have a Joomla 3.6.2 news website. Here we display news etc etc.
Now daily we upload tons or articles, we have a login system for paid subscribers.
The problem is that I have some "long slow queries' running which is eating up my resources.
I have 4 CPU cores 3.0 GHz and 7GB of RAM. Every few seconds the CPU and RAM kick up to a 100% and then drop slowly again. Which results in a 503 on the website.
As you can see this is quite annoying. Now my host told me that the following queries are causing this issue;
1. Executed 3h 55m 25s ago for 47.63166 sec on Database --> *********
Date: 2016-10-11 05:25:56 Query_time: 47.631660 Rows_examined: 179766: Rows_sent 10757 Lock_time: 0.000539
SELECT a.id, a.title, a.alias, a.introtext, a.fulltext, a.checked_out,
a.checked_out_time, a.catid, a.created, a.created_by, a.created_by_alias,
CASE WHEN a.modified = '0000-00-00 00:00:00'
THEN a.created ELSE a.modified END as modified, a.modified_by,
uam.name as modified_by_name,
CASE WHEN a.publish_up = '0000-00-00 00:00:00'
THEN a.created ELSE a.publish_up END as publish_up,
a.publish_down, a.images, a.urls, a.attribs, a.metadata,
a.metakey, a.metadesc, a.access, a.hits, a.xreference, a.featured,
a.language, LENGTH(a.fulltext) AS readmore,
CASE WHEN badcats.id is not null THEN 0 ELSE a.state END AS state,
c.title AS category_title, c.path AS category_route,
c.access AS category_access, c.alias AS category_alias,CASE WHEN a.created_by_alias > ' ' THEN a.created_by_alias ELSE ua.name END AS author,ua.email AS author_email,parent.title as parent_title, parent.id as parent_id, parent.path as parent_route, parent.alias as parent_alias,ROUND(v.rating_sum / v.rating_count, 0) AS rating, v.rating_count as rating_count,c.published, CASE WHEN badcats.id is null THEN c.published ELSE 0 END AS parents_published FROM sxm_content AS a LEFT JOIN sxm_categories AS c ON c.id = a.catid LEFT JOIN sxm_users AS ua ON ua.id = a.created_by LEFT JOIN sxm_users AS uam ON uam.id = a.modified_by LEFT JOIN sxm_categories as parent ON parent.id = c.parent_id LEFT JOIN sxm_content_rating AS v ON a.id = v.content_id LEFT OUTER JOIN (SELECT cat.id as id FROM sxm_categories AS cat JOIN sxm_categories AS parent ON cat.lft BETWEEN parent.lft AND parent.rgt WHERE parent.extension = 'com_content' AND parent.published != 1 GROUP BY cat.id ) AS badcats ON badcats.id = c.id WHERE a.access IN (1,1,5) AND c.access IN (1,1,5) AND CASE WHEN badcats.id is null THEN a.state ELSE 0 END = 1 AND (a.publish_up = '0000-00-00 00:00:00' OR a.publish_up <= '2016-10-11 10:25:09') AND (a.publish_down = '0000-00-00 00:00:00' OR a.publish_down >= '2016-10-11 10:25:09') ORDER BY c.lft, CASE WHEN a.publish_up = '0000-00-00 00:00:00' THEN a.created ELSE a.publish_up END DESC , a.created;
I am quite new when it comes to these queries and correct me if I am wrong, I see that the query is trying to pull info from the articles table.
I am not sure why it would go through the whole table, I don't display all the articles on 1 page, nor do I have pagination where all articles from 1 category or more are being displayed.
This just happened out of the blue. I didn't make any changes to the website, no updating. Only thing I installed was a SSL Certificate.
I am also using CloudFlare as my CDN which takes quite a big load of the web-server. I don't use the Joomla cache but instead I use JOTCache simply because of the fact that I can exclude certain position on the website that I don't want cached.
We have around the 5k unique visitors per day.

TSQL Partitioning to COUNT() only subset of rows

I have a query that I am working on that, for every given month and year in a sales table, returns back a SUM() of the total items ordered as well as a count of the distinct number of accounts ordering items and a couple break down of SUm()s on various product types. See the query below for an example:
SELECT
YearReported,
MonthReported,
COUNT(DISTINCT DiamondId) as Accounts,
SUM(Quantity) as TotalUnitsOrdered,
SUM(CASE P.ProductType WHEN 1 THEN Quantity ELSE 0 END) as MonthliesOrdered,
SUM(CASE P.ProductType WHEN 1 THEN 0 ELSE Quantity END) as TPBOrdered
FROM
RetailOrders R WITH (NOLOCK)
LEFT JOIN
Products P WITH (NOLOCK) ON R.ProductId = P.ProductId
GROUP BY
YearReported, MonthReported
The problem I am facing now is that I also need to get the count of distinct accounts broken out based on another field in the dataset. For example:
SELECT
YearReported,
MonthReported,
COUNT(DISTINCT DiamondId) as Accounts,
SUM(Quantity) as TotalUnitsOrdered,
SUM(CASE P.ProductType WHEN 1 THEN Quantity ELSE 0 END) as MonthliesOrdered,
SUM(CASE P.ProductType WHEN 1 THEN 0 ELSE Quantity END) as TPBOrdered,
SUM(CASE IsInitial WHEN 1 THEN Quantity ELSE 0 END) as InitialOrders,
SUM(CASE IsInitial WHEN 0 THEN Quantity ELSE 0 END) as Reorders,
COUNT(/*DISTINCT DiamndId WHERE IsInitial = 1 */) as InitialOrderAccounts
FROM
RetailOrders R WITH (NOLOCK)
LEFT JOIN
Products P WITH (NOLOCK) ON R.ProductId = P.ProductId
GROUP BY
YearReported, MonthReported
Obviously we would replace the commented out section in the last SUM with something that would not throw an error. I just added that for illustrative purposes.
I feel like this can be done using the Partition methods in SQL, but I have to admit that I just am not very good with them and cant figure out how to do this. And the MS documentation online for Partitions really just makes my head hurt after reading it last night.
EDIT: I mistakenly has the last aggregate function as sum and I meant for it to be a COUNT().
So to help clarify, COUNT(DISTINCT DiamondId) will give me back a count of all unique DiamondId values in the set but I also need to get a COUNT() of all Unique Diamond Id values in the set whose corresponding IsInitial flag is set to 1
Just a matter of nulling the ones that don't qualify:
count(distinct
case
when IsInitial = 1 then DiamndId
/* else null */
end
)

how to use count, case and Distinct together in sql server

I want to create a statement but i not success to complete this. can you please take a look and let me know what i need to do to complete this. My problem due how to add these two part in my query.
I want to look at the last 30 days of orders for each DRV1NUM. If that driver has worked 0 days then say ‘NOT ACTIVE’. If the driver has worked more than 15 days then ‘FULL TIME’ and less than 15 days is ‘PART TIME’.
In this one, I want to look at the last 30 days of orders and compare the left(4) of DRIVERNUM to the entire DRIVERNUM. In some instances, we have drivers where there is a 5th letter after the left 4.I want to look at the last 30 days of orders and if the left(4) DRV1NUM has more than one DRV1NUM WHEN looking at all characters, then SAY ‘MASTER’
SELECT DISTINCT DRVLICNUM,DOB,COUNTRY,CREDITLIMIT,DRIVERNUM=LEFT(DRIVERNUM,4),
SSN,D.VEHICLE,PHN1,DRVLICST,HOST,VEHICLE_MC,
VEHICLE_DOT,BACK_APPROVED=CASE WHEN PROBDATE IS NOT NULL THEN 'YES' ELSE 'NO' END
-- CASE WHEN COUNT(DISTINCT O.DROPDATE)=0 IN LAST 30 DAYS THEN 'NOT ACTIVE' WHEN COUNT(DISTINCT O.DROPDATE)>15 IN LAST 30 DAYS THEN 'FULL TIME' WHEN COUNT(DISTINCT O.DROPDATE)>=1 AND <=15 THEN 'PART TIME' IN LAST 30 DAYS ELSE NULL AS DAYSWORKED,
-- --CASE WHEN COUNT(DISTINCT O.DRV1NUM OF LEFT(DRIVERNUM,4 )>0 IN LAST 30 DAYS OF ORDERS>1 THEN 'MASTER IC' ELSE NULL AS MASTER
/* ABOVE TWO STATEMENT I WANT TO ADD */
FROM DRIVER D
FULL OUTER JOIN orde_ O ON O.DRV1ID=D.DRIVERID
AND ISNUMERIC(DRIVERNUM)=1 and DRIVERNUM NOT IN ('1010')
Expected Output That i want
DRVLICNUM Employee DOB COUNTRY ACTIVESTATUS
---------------------------------------------------------
055243324 CONTRACTOR 1985-04-13 ATLANTA FULL TIME
Here the ActiveStatus is Active because the driver worked more than 15 days in past 15 days or if it will less then 15 days it will be 'Part Time'
I don't have access to google drive link which you shared.
However, you will have to use CTE (common table expression) to get count of days and then use it compute value of ActiveStatus column.
Try using below code:
;
WITH CTE1
AS(
SELECT D.DRIVERID,
COUNT(DISTINCT O.DROPDATE) AS DayCount
FROM DRIVER AS D
LEFT JOIN ORDER AS O ON D.DRIVERID=O.DRV1ID AND O.DROPDATE BETWEEN CONVERT(DATE,DATEADD(DAY,-30,GETDATE())) AND GETDATE()
WHERE ISNUMERIC(D.DRIVERNUM)=1 AND D.DRIVERNUM NOT IN ('1010')
GROUP BY D.DRIVERID
)
SELECT DRVLICNUM,DOB,COUNTRY,CREDITLIMI,...
CASE
WHEN DayCount=0 THEN 'NOT ACTIVE'
WHEN DayCount<=15 THEN 'PART TIME'
WHEN DayCount>=30 THEN 'FULL TIME'
END AS ACTIVESTATUS
FROM CTE1 AS C
JOIN DRIVER AS D ON C.DRIVERID=D.DRIVERID
here is two siple queries for the first one:
1) select order by dates and group by driver (if there no more than one order per day):
select o.DRIVERID
, count(*) as cnt
from orde_ o
where o.DROPDATE betwen GETDATE() AND DATEADD(DAY,-30,GETDATE())
group by o.DRIVERID
2) select drivers and join groupped orders
select case
when o.ctn >= 15 then 'FULL TIME'
when o.ctn > 0 then 'PART TIME'
else 'NOT ACTIVE'
end
, <other fields you want>
from DRIVER as D
left join <query above> as o
on o.DRIVERID = d.DRIVERID
for the second one:
select left(d.DRIVERID, 4), count(*) as cnt
from DRIVER as D
group by left(d.DRIVERID, 4)
having count(*) > 1
and just join it, if is not null then compare whole id's

Look at data in one date range and count from another date range

I'm stuck on a query where I am trying to get information on just customers that are newly acquired during a certain date range.
I had need to get a list of customers who placed their first order (of all time) in the first 6 months of the year. I then need to get total of their invoices, first invoice date, last invoice date, and count of orders for just the last 6 months.
I used a HAVING clause to ensure that I am just looking at customers that placed their first order in that 6 month period, but since we are past that period now, the total invoice info and order count information would include orders placed after this time. I considered including a restriction in the HAVING clause for the 'last invoice date', but then I am eliminating customers whose first order date was in the 6 month block, but also ordered after that. I'm not sure what to do next and am not having luck finding similar questions. Here is what I have so far:
SELECT c.customer, MAX(c.name) AS Name,
SUM(
CASE WHEN im.debit = 0
THEN im.amount * -1
ELSE im.amount
END
) AS TotalInvoiceAmount,
MIN(
im.date) AS FirstInvoiceDate,
MAX(
im.date) AS LastInvoiceDate,
COUNT(DISTINCT om.[order]) AS OrderCount
FROM invoicem im
INNER JOIN customer c ON im.customer = c.customer
FULL JOIN orderm om ON im.customer = om.customer
WHERE im.amount <> 0
GROUP BY c.customer
HAVING MIN(im.date) BETWEEN '01-01-2015' AND '06-30-2015'
ORDER BY c.customer
You can put the first 6 months qualification as a subquery. This would also work as a CTE
declare #startDate date = dateadd(month,-6,getdate())
SELECT c.customer, MAX(c.name) AS Name,
SUM(
CASE WHEN im.debit = 0
THEN im.amount * -1
ELSE im.amount
END
) AS TotalInvoiceAmount,
MIN(
im.date) AS FirstInvoiceDate,
MAX(
im.date) AS LastInvoiceDate,
COUNT(DISTINCT om.[order]) AS OrderCount
FROM invoice im
INNER JOIN (SELECT customer from invoice
GROUP BY customer
HAVING MIN(date) BETWEEN '01-01-2015'
AND '06-30-2015') im2
ON im.customer = im2.customer
INNER JOIN customer c ON im.customer = c.customer
FULL JOIN orderm om ON im.customer = om.customer
WHERE im.amount <> 0
AND im.date >= #startdate
GROUP BY c.customer
ORDER BY c.customer

Resources