I have sql something like
select
name,col2,col3,date
from
table1 join on few tables
And result is
name col2 col3 date
a a a datetime1
a a a datetime1
b b b datetime2
b b b datetime3
and i dont know how to do, but i need to replace date column with column which will
shows count of working days for every name/row
I though about subquery like
,(select COUNT(distinct DATENAME(dw, date) NOT IN ('Saturday', 'Sunday')) where name = '...' from ... where ...) as WorkingDays
but i need help to get it working, thank you.
Perhaps you want this:
SELECT Name, C2,
WorkingDays = Sum(CASE WHEN Datename(DW, [date])IN( 'Saturday', 'Sunday' )
THEN 0 ELSE 1 END)
OVER (PARTITION BY Name)
FROM dbo.data
Here is the sql-fiddle with your sample-data: http://sqlfiddle.com/#!3/1279f/14/0
if my understanding is not wrong you just need a groupby of other columns and count of 'date'
select
name,col2,col3,count(date) as no_of_days
from
table1 join on few tables
where DATENAME(dw, date) NOT IN ('Saturday', 'Sunday')
group by name,col2,col3
Related
I'm working on sales data and I want to know if Customer A purchased product X from more than one provider within 3 days and I'm working on only one date Claim Date
I Can't find T-Sql query for it
for example
SELECT CusName,ProdName,ProvName
FROM table1
WHERE [Claim Date] between Day([Claim Date]) and DATEADD (Day ,-3 , [Claim Date]
A WHERE EXISTS clause should do the job:
SELECT CusName,ProdName,ProvName
FROM table1 a
WHERE EXISTS (
SELECT 1 FROM table1 b WHERE
b.CusName=a.CusName AND
b.ProdName=a.ProdName AND
b.ProvName!=a.ProvName AND
ABS(DATEDIFF(day,a.ClaimDate,b.ClaimDate))<3
)
You can use the below code for that
SELECT t1.CusName,t1.ProdName,t1.ProvName,t2.ProvName
FROM table t1
JOIN table t2 ON t1.CusName=t2.CusName AND t1.ProdName=t2.ProdName
WHERE t1.ProvName!=t2.ProvName
AND ABS(DATEDIFF(day,t1.ClaimDate,t2.ClaimDate)) = 3
You need a having clause and a count of the providers:
SELECT CusName, COUNT(DISTINCT ProvName) Provider_count
FROM table1
WHERE [Claim Date] between Day([Claim Date]) and DATEADD (Day ,-3 , [Claim Date]
AND ProdName = 'X'
GROUP BY CusName
HAVING COUNT(DISTINCT ProvName) > 1
Note, you do not need to include the count in the select clause, but you do need it in the having clause.
I'm writing a query to return a table of booking data for an event. I've used a SUM aggregate to group the number of daily bookings. I'd now like to create a column with a cumulative running total.
I can't make my query work because (I'm presuming) it doesn't like the aliased column title being included in the aggregate function.
Please can anyone advise me on the best approach to make this work?
SELECT
'Recruitment Event' Event,
CAST(ep.CREATIONDATE AS date) AS 'Date of Booking',
SUM(CASE
WHEN ep.CREATIONDATE IS NOT NULL THEN 1
ELSE 0
END) 'Total Bookings',
(SELECT
SUM('Total Bookings')
FROM EVENTPLACE AS ep
WHERE CAST(ep.CREATIONDATE AS date) <= CAST(ep.CREATIONDATE AS date))
'Running Total'
FROM EVENTPLACE AS ep
LEFT JOIN EVENTMODULE AS em
ON em.EVENTMODULENO = ep.EVENTMODULENO
WHERE em.EVENTMODULENO = '11111111-ABCD-1234-1234-1010101010'
GROUP BY CAST(ep.CREATIONDATE AS date)
ORDER BY CAST(ep.CREATIONDATE AS date) DESC
try this
SELECT
[Event] = 'Recruitment Event' ,
[Date of Booking] = CAST(ep.CREATIONDATE AS DATE),
[Total Bookings] = COUNT(ep.CREATIONDATE),
[Running Total] = SUM(COUNT(ep.CREATIONDATE)) OVER (ORDER BY CAST(ep.CREATIONDATE AS DATE) DESC)
FROM
EVENTPLACE AS ep
WHERE
EXISTS (SELECT
*
FROM
EVENTMODULE em
WHERE
em.EVENTMODULENO = ep.EVENTMODULENO
AND em.EVENTMODULENO = '11111111-ABCD-1234-1234-1010101010')
GROUP BY
CAST(ep.CREATIONDATE AS DATE)
ORDER BY
CAST(ep.CREATIONDATE AS DATE) DESC
COUNT(ep.CREATIONDATE) will ignore null values with the same result as your SUM(CASE)
You dont really have to use EXISTS, but you should probably change your LEFT JOIN to a JOIN since you're using the em.EVENTMODULENO in the WHERE statement
SUM(COUNT(ep.CREATIONDATE)) OVER () will give you running total of the count. You use ORDER BY in the OVER to determine the order of the SUM. Since you're ordering by CAST(ep.CREATIONDATE AS DATE) DESC you can just use that in the OVER()
You are getting error because of these lines..
SUM (case when ep.CREATIONDATE IS NOT NULL then 1 else 0 end) 'Total Bookings',
(SELECT SUM ('Total Bookings') FROM EVENTPLACE
You are trying to select alias which was defined in same phase and you are passing it as string .your query wont work unless you correlate it with main table which you are not doing..
Below query works from SQLServer 2012
;with cte
as
(
SELECT 'Recruitment Event' Event,
cast(ep.CREATIONDATE as date) as 'Date of Booking',
SUM (case when ep.CREATIONDATE IS NOT NULL then 1 else 0 end) 'Total Bookings',
FROM EVENTPLACE as ep
LEFT JOIN EVENTMODULE as em ON em.EVENTMODULENO=ep.EVENTMODULENO
WHERE em.EVENTMODULENO = '11111111-ABCD-1234-1234-1010101010'
GROUP BY cast(ep.CREATIONDATE as date)
)
select *,
sum([Total Bookings])
over (order by [Date of Booking] ROWS UNBOUNDED ECEDING ) as 'Runningtotal'
from
cte
The problem is that there is a SUM() function in your select statement, but not all the other columns are included in your group by clause.
The solution is that add an OVER(ORDER BY ...) clause after your SUM function to calculate the running total.
SELECT
'Recruitment Event' Event,
CAST(ep.CREATIONDATE AS date) AS 'Date of Booking',
SUM(CASE
WHEN ep.CREATIONDATE IS NOT NULL THEN 1
ELSE 0
END)OVER(ORDER BY CAST(ep.CREATIONDATE AS date) DESC) 'Running Total',
FROM EVENTPLACE AS ep
LEFT JOIN EVENTMODULE AS em
ON em.EVENTMODULENO = ep.EVENTMODULENO
WHERE em.EVENTMODULENO = '11111111-ABCD-1234-1234-1010101010'
CAST(ep.CREATIONDATE AS date) DESC
I'm doing a simple count query for an SSRS chart, and while it looks like a common question, I've not really found an answer that suits my situation. This is my query:
SELECT TOP 30 CAST(qa.Created As Date) As 'Date',
COUNT(qa.Created) As 'Count'
FROM QAs qa
GROUP BY CAST(qa.Created As Date)
ORDER BY 'Date' DESC
This returns something like:
Date | Count
2014-11-10 | 2
2014-11-08 | 3
2014-11-07 | 8
Which when put into a line chart, doesn't show the dip down to 0 on the 9th and is a bit confusing for my users. What I want to do is have all of the last 30 days appear in order, even if they are at 0. I've been told to do this with COALESCE() but I can't seem to get that working either. Where am I going wrong?
Use a Recursive CTE to generate dates for last 30 days.
;WITH cte
AS (SELECT Cast(dateadd(day,-30,Getdate()) AS DATE) AS dates
UNION ALL
SELECT Dateadd(day, 1, dates)
FROM cte
WHERE dates < cast(Getdate() as date)
SELECT a.Dates AS [Date],
Count(qa.Created) AS [Count]
FROM cte a
LEFT JOIN QAs qa
ON a.dates = Cast(qa.Created AS DATE)
GROUP BY a.Dates
ORDER BY a.Dates
I'd probably go with NoDisplayName's recursive CTE but for an alternative, if you happen to be stuck in something prior to 2005 which I was for a long time.
--Build a table of dates
DECLARE #dates AS TABLE([date] date)
DECLARE #i int
SET #i = 30
WHILE #i > 0
BEGIN
INSERT INTO #dates([date])
SELECT DATEADD(d, -1 * #i, GETDATE())
SET #i = (#i - 1)
END
--Join into those dates so that no date is excluded
SELECT [date], SUM(dateCount)
FROM (
SELECT d.[date], CASE WHEN qa.Created IS NULL THEN 0 ELSE 1 END AS dateCount
FROM #dates d
LEFT JOIN QAs qa ON CAST(qa.Created AS date) = d.[date]
) AS dateCounts
GROUP BY [date]
I have the following query
SELECT MONTH, COUNT(DISTINCT VISITS) AS BRAND_VISITS, NULL AS NONB_VISITS
FROM Table1
WHERE KEYWORD_TYPE = BRAND(
AND DATE >= '2013-01-01'
GROUP BY MONTH
UNION ALL
SELECT MONTH, NULL, COUNT(DISTINCT VISITS) AS NONB_VSTS
FROM Table1
WHERE KEYWORD_TYPE = NON-BRAND
AND DATE >= '2013-01-01'
GROUP BY MONTH
I get the following results:
1 352540 NULL
2 309834 NULL
3 228764 NULL
4 236054 NULL
5 218096 NULL
6 172527 NULL
1 NULL 5337
2 NULL 14120
3 NULL 9954
4 NULL 23755
5 NULL 19771
6 NULL 30797
However, what I want is inline results without NULLS
1 352540 5337
2 309834 14120
3 228764 9954
4 236054 23755
5 218096 19771
6 172527 30797
You can do this with using a single statement with CASE or with an JOIN on month instead of a UNION. If you take the join approach you may need to account for null values (no visist for a keyword in a month). You will want to profile them to see which is faster with your data and table structure. It is really all about the indexes and the amount of data you need to aggregate.
Assuming you don't have to worry about nulls based on the counts in your example, here is what you want.
SELECT brand.month, brand.brand_visits,nonbrand.non_brand_visits
FROM (SELECT month, COUNT(visits) AS brand_visits
FROM Table1
WHERE keyword_type = 'BRAND'
AND date >= '2013-01-01'
GROUP BY month) brand
INNER JOIN
(SELECT month, COUNT(visits) AS non_brand_visits
FROM Table1
WHERE keyword_type = 'NON-BRAND'
AND date >= '2013-01-01'
GROUP BY month) nonbrand
ON brand.month=nonbrand.month
Here is the CASE approach. You should profile based on your actual data you are aggregating and your indexes to see which method is faster.
SELECT month,
SUM(CASE WHEN keyword_type = 'BRAND' THEN 1 ELSE 0 END) AS brand_visits,
SUM(CASE WHEN keyword_type = 'NON-BRAND' THEN 1 ELSE 0 END) AS non_brand_visits
FROM Table1
WHERE date >= '2013-01-01'
GROUP BY month
Finally, you did not provide table structure or example data so I made some assumptions above. I strongly believe you did not need the COUNT(DISTINCT in your original statement. I have removed it and verified the two statement above yield the same results. If COUNT(DISTINCT is required then the CASE approach will not work but the join approach will still work fine.
Using your columns:
SELECT month,
count(distinct CASE WHEN keyword_type = 'BRAND' THEN visits END) AS BRAND_VISITS,
count(distinct CASE WHEN keyword_type = 'NON-BRAND' THEN visits END) AS NONB_VSTS
FROM Table1
WHERE date >= '2013-01-01'
and keyword_type in ('BRAND','NON-BRAND')
GROUP BY month
Am tempted to believe that month is simply the month from the date column, I would prefer this solution, it con cover more years than 1 and the same query will still be valid in the year 2014
SELECT cast(dateadd(month, datediff(month, 0, date), 0) as date) month,
count(distinct CASE WHEN keyword_type = 'BRAND' THEN visits END) AS BRAND_VISITS,
count(distinct CASE WHEN keyword_type = 'NON-BRAND' THEN visits END) AS NONB_VSTS
FROM Table1
WHERE date >= '2013-01-01'
and keyword_type in ('BRAND','NON-BRAND')
GROUP BY datediff(month, 0, date)
If you want to stick with your old script, you can fix it this way:
SELECT MONTH, max(BRAND_VISITS) BRAND_VISITS, max(NONB_VISITS) NONB_VISITS
FROM
(
SELECT MONTH, COUNT(DISTINCT VISITS) AS BRAND_VISITS, NULL AS NONB_VISITS
FROM Table1
WHERE KEYWORD_TYPE = 'BRAND'
AND DATE >= '2013-01-01'
GROUP BY MONTH
UNION ALL
SELECT MONTH, NULL, COUNT(DISTINCT VISITS) AS NONB_VSTS
FROM Table1
WHERE KEYWORD_TYPE = 'NON-BRAND'
AND DATE >= '2013-01-01'
GROUP BY MONTH
) a
GROUP BY MONTH
Table :tbl_user
dateofregistration ID registrationstate
6-03-11 3 0
6-03-11 1 0
6-03-11 2 1
7-03-11 2 1
7-03-11 1 1
how can I display result like this for sql server 2008 express
date TotalID(count) Total State(0 only)
6-03-11 3 2
7-03-11 2 0
I have tried with this
SELECT CONVERT(varchar(10), dateofregistration, 103) AS Date,
(select COUNT(ID)) AS Subbase,
(Select Count(ID)from tbl_User where (registrationstate='0')) AS Totalchurn
FROM tbl_User
GROUP BY CONVERT(varchar(10), dateofregistration, 103);
but wrong result.Any help plz.
How about;
select
cast(dateofregistration as date),
count(distinct id), --or * for all
sum(
case registrationstate when '0' then 1 else 0 end
)
from tbl_user
group by cast(dateofregistration as date)
order by 1
2011-06-03 3 2
2011-07-03 2 0
SELECT CONVERT(varchar(10), dateofregistration, 103) AS Date,
COUNT(1) AS Subbase,
SUM(CASE WHEN registrationstate='0' THEN 1 ELSE 0 END) AS Totalchurn
FROM tbl_User
GROUP BY CONVERT(varchar(10), dateofregistration, 103)
ORDER BY 1
You were nearly there. You don't need a subselect for COUNT(ID) since that is handled by the GROUP BY. You group by date, and so the count will be the number of IDs within each date. I've made the count distinct, just in case you can have multiple registrations of the same ID on one day.
Your subquery was almost right - it needs to be correlated with the main query by selecting rows with the same registration date.
SELECT CONVERT(varchar(10), dateofregistration, 103) AS Date,
COUNT(DISTINCT ID) AS TotalID,
(Select Count(*) from tbl_User t2 where (registrationstate='0') AND t2.registrationdate=t1.registrationdate) AS Totalchurn
FROM tbl_User t1
GROUP BY CONVERT(varchar(10), dateofregistration, 103);