Count Query in Select Statement - sql

May I ask someone why the two queries below don't output the same result using MSSMS? What do I have to add to the second one to get me the first output.
Table
|----------------------------------------|
| RoomBase |
|---------------------|------------------|
| CustomBit1 | Date |
| 1 | 2018-11-01 |
| 1 | 2018-11-01 |
| 1 | 2018-11-01 |
| 1 | 2018-11-01 |
| 1 | 2018-11-01 |
| 1 | 2018-10-01 |
| 0 | 2018-10-01 |
| 0 | 2018-10-01 |
| 0 | 2018-10-01 |
| 1 | 2018-10-01 |
|---------------------|------------------|
Result from first query. [Desired Result.]
|---------------------|
| Count |
|---------------------|
| 2 |
| 5 |
|---------------------|
Result from second query. [Undesired result.]
|---------------------|
| Count |
|---------------------|
| 630 |
| 630 |
|---------------------|
630 is coming from the original amount of the data.
SELECT ISnull(Count(1),0) FROM dbo.[RoomBase]
WHERE dbo.[RoomBase].CustomBit1 = 1
GROUP BY [RoomBase].Date
SELECT (SELECT ISnull(Count(1), 0) FROM dbo.[RoomBase]
WHERE dbo.[RoomBase].CustomBit1 =1)
FROM dbo.[RoomBase]
GROUP BY [RoomBase].Date
All help is appreciated...
Thank you!

You should also filter your sub query by date
SELECT (
SELECT ISnull(Count(1), 0) FROM dbo.[RoomBase] RB WHERE RB.CustomBit1 = 1
AND RB.Date = [RoomBase].Date
)
FROM dbo.[RoomBase]
GROUP BY [RoomBase].Date

First Query will count all records that has CustomBit1 = 1 after grouped them by Date.
The second one, will count all records that has CustomBit1 = 1 (without grouping them), because you didn't include the group by inside the sub-query.
So, you'll have to do something like this in the second query :
SELECT
(
SELECT TOP 1
COUNT(*)
FROM RoomBase
WHERE
CustomBit1 = 1
GROUP BY [Date]
)
FROM RoomBase
Also, ISNULL() is not needed with COUNT() or SUM() functions. As these functions will always return an integer, and never return a NULL.

Related

How do i get the latest user udpated column value in a table based on timestamp entry on a different table in SQL Server?

I have a temp table #StatusInfo with the following data
+---------+--------------+-------+-------------------------+--+
| OrderNo | GroupLineNum | Type1 | UpdateDate | |
+---------+--------------+-------+-------------------------+--+
| Order85 | NULL | 1 | 2019-11-25 05:15:55.000 | |
+---------+--------------+-------+-------------------------+--+
| Order86 | NULL | 1 | 2019-11-25 05:15:55.000 | |
+---------+--------------+-------+-------------------------+--+
| Order86 | 2 | 2 | 2019-11-25 05:32:23.773 | |
+---------+--------------+-------+-------------------------+--+
| Order87 | NULL | 1 | 2019-11-25 05:15:55.000 | |
+---------+--------------+-------+-------------------------+--+
| Order87 | 1 | 2 | 2019-11-25 05:43:37.637 | | B
+---------+--------------+-------+-------------------------+--+
| Order87 | 2 | 2 | 2019-11-25 05:42:32.390 | | A
+---------+--------------+-------+-------------------------+--+
| Order88 | NULL | 1 | 2019-11-25 06:35:13.000 | |
+---------+--------------+-------+-------------------------+--+
| Order88 | 1 | 2 | 2019-11-25 06:39:16.170 | |
+---------+--------------+-------+-------------------------+--+
Any update the user does on an order will be pulled into this temp table. Type 1 column with value 2 denotes a 'Required Date' field change by the user. The timestamp when the user made the change is the last column.
I have another temp table #LineInfo with the following data. This table is created by joining other tables and a left join with the above table too. The 'LineNum' column from below table will match the 'GroupLineNum' column in the above table for Type1=2
+---------+-----------+---------+------------+-------------------------+-------+
| OrderNo | RowNumber | LineNum | TotalCost | ReqDate | Type1 |
+---------+-----------+---------+------------+-------------------------+-------+
| Order85 | 1 | 1 | 309.110000 | 2019-10-30 23:59:00.000 | 1 |
+---------+-----------+---------+------------+-------------------------+-------+
| Order85 | 2 | 2 | 265.560000 | 2019-10-30 23:59:00.000 | 1 |
+---------+-----------+---------+------------+-------------------------+-------+
| Order86 | 1 | 1 | 309.110000 | 2019-10-30 23:59:00.000 | 1 |
+---------+-----------+---------+------------+-------------------------+-------+
| Order86 | 2 | 2 | 265.560000 | 2019-12-28 23:59:00.000 | 2 |
+---------+-----------+---------+------------+-------------------------+-------+
| Order87 | 1 | 1 | 309.110000 | 2020-01-31 23:59:00.000 | 2 |
+---------+-----------+---------+------------+-------------------------+-------+
| Order87 | 2 | 2 | 265.560000 | 2020-01-01 23:59:00.000 | 2 |
+---------+-----------+---------+------------+-------------------------+-------+
| Order88 | 1 | 1 | 309.110000 | 2019-11-29 23:59:00.000 | 2 |
+---------+-----------+---------+------------+-------------------------+-------+
| Order88 | 2 | 2 | 265.560000 | 2019-12-31 23:59:00.000 | 2 |
+---------+-----------+---------+------------+-------------------------+-------+
I will be joining #lineInfo with other tables to generate a new table with only one record for an orderno. Its grouped by orderno.
What I need to do is ensure that the new selectquery will have a column 'ReqDate' which will be the latest ReqDate value for the order.
For example, Order87 has two lines in the order. User updated Line 2 first at '2019-11-25 05:42:32.390' as seen in the row marked 'A' followed by Line 1 marked B # '2019-11-25 05:43:37.637 ' from the first table.
The new query should have the data from LineInfo and only the 'ReqDate' value matching the 'LineNum' that has the maximum of 'UpdateDate' column for Type1=2 and group by orderno.
So in our example, the output should have the ReqDate value '2020-01-31 23:59:00.000'.
In short, an order should have the most recently updated required date. Order can have multiple line items where reqdate is udpated. If there is no entry in #StatusInfo table with Type2 for an order, then any one of the ReqDate value from the #LineInfo table will suffice. Maybe the first line
I wrote something like this but it doesnt pull orders without any entry in StatusInfo table. Those orders will have a default value even though user didnt udpate and i am not sure how to join the result of this with LineInfo table to set the latest value
Select SIT.Orderno, max_date,grouplinenum
from #StatusInfo SIT
inner join
(SELECT Orderno, MAX(ActDate) as max_date
FROM #StatusInfo SI
WHERE SI.Type1=2
GROUP BY SI.Orderno)a
on a.Orderno = SIT.Orderno and a.max_date = SIT.ActDate
This is what I did. I created the blow CTE to load orders with req date change in order of Updated date and assigned it row number. Record with row number 1 will be the most recently updated date
;WITH cteLatestReqDate AS ( --We need to pull the latest ReqDate value the user set. So we are are ordering the SIT table by ActDate and assigning a row number and respective line's required date here
SELECT SIT.OrderNo, SIT.UpdateDate, SIT.GroupLineNum, LLI.ReqDate,
ROW_NUMBER() OVER (PARTITION BY SIT.OrderNo ORDER BY ActDate DESC) AS RowNum
FROM #StatusInfo SIT INNER JOIN #LineLevelInfo LLI ON SIT.OrderNo = OI.OrderNo AND SIT.GroupLineNum = LLI.LineNum
WHERE SIT.Type1 = 2
)
and then I added the below condition to my select query. Below select query is partial
SELECT
CASE WHEN MAX(LRD.ReqDate) IS NULL THEN CAST(FORMAT(MAX(LLI.ReqDate), 'yyMMdd') AS NVARCHAR(10))
ELSE CAST(FORMAT(MAX(LRD.ReqDate), 'yyMMdd') AS NVARCHAR(10)) END AS LatestReqDate
FROM #LineLevelInfo LLI
LEFT JOIN(SELECT * FROM cteLatestReqDate WHERE RowNum = 1)LRD ON LRD.OrderNo = LLI.OrderNo And LRD.GroupLineNum = LLI.LineNum

Today vs weeks ago with aggregate function

I'm working on the following presto/sql query using inline filter to get side by side comparison of current date range vs weeks ago data.
In my case query current date range is 2017-09-13 to 2017-09-14.
So far I'm able to get the following results, but unfortunately this is not what I want.
Any kind of help would be greatly appreciated.
SELECT
DATE_TRUNC('day',DATE_PARSE(CAST(sample.datep AS VARCHAR),'%Y%m%d')) AS date,
CAST(SUM(sample.page_views) FILTER (WHERE sample.datep BETWEEN 20170913 AND 20170914) AS DOUBLE) AS page_views,
CAST(SUM(sample.page_views) FILTER (WHERE sample.datep BETWEEN 20170906 AND 20170907) AS DOUBLE) AS page_views_weeks_ago
FROM
sample
WHERE
(
datep BETWEEN 20170906 AND 20170914
)
GROUP BY
1
ORDER BY
1 ASC
LIMIT 50
Actual result:
+------------+------------+----------------------+
| date | page_views | page_views_weeks_ago |
+------------+------------+----------------------+
| 2017-09-06 | 0 | 990,929 |
| 2017-09-07 | 0 | 913,802 |
| 2017-09-08 | 0 | 0 |
| 2017-09-09 | 0 | 0 |
| 2017-09-10 | 0 | 0 |
| 2017-09-11 | 0 | 0 |
| 2017-09-12 | 0 | 0 |
| 2017-09-13 | 1,507,715 | 0 |
| 2017-09-14 | 48,625 | 0 |
+------------+------------+----------------------+
Expected result:
+------------+------------+----------------------+
| date | page_views | page_views_weeks_ago |
+------------+------------+----------------------+
| 2017-09-13 | 1,507,715 | 990,929 |
| 2017-09-14 | 48,625 | 913,802 |
+------------+------------+----------------------+
You can achieve with joining a table with itself as a previous day. For brevity, I assume that we have a date field so that date substructions can be done easily.
SELECT date,
SUM(curr.page_views) AS page_views,
SUM(prev.page_views) AS page_views_weeks_ago
FROM sample curr
JOIN sample prev ON curr.date - 7 = prev.date
GROUP BY 1
ORDER BY 1 ASC

Union in outer query

I'm attempting to combine multiple rows using a UNION but I need to pull in additional data as well. My thought was to use a UNION in the outer query but I can't seem to make it work. Or am I going about this all wrong?
The data I have is like this:
+------+------+-------+---------+---------+
| ID | Time | Total | Weekday | Weekend |
+------+------+-------+---------+---------+
| 1001 | AM | 5 | 5 | 0 |
| 1001 | AM | 2 | 0 | 2 |
| 1001 | AM | 4 | 1 | 3 |
| 1001 | AM | 5 | 3 | 2 |
| 1001 | PM | 5 | 3 | 2 |
| 1001 | PM | 5 | 5 | 0 |
| 1002 | PM | 4 | 2 | 2 |
| 1002 | PM | 3 | 3 | 0 |
| 1002 | PM | 1 | 0 | 1 |
+------+------+-------+---------+---------+
What I want to see is like this:
+------+---------+------+-------+
| ID | DayType | Time | Tasks |
+------+---------+------+-------+
| 1001 | Weekday | AM | 9 |
| 1001 | Weekend | AM | 7 |
| 1001 | Weekday | PM | 8 |
| 1001 | Weekend | PM | 2 |
| 1002 | Weekday | PM | 5 |
| 1002 | Weekend | PM | 3 |
+------+---------+------+-------+
The closest I've come so far is using UNION statement like the following:
SELECT * FROM
(
SELECT Weekday, 'Weekday' as 'DayType' FROM t1
UNION
SELECT Weekend, 'Weekend' as 'DayType' FROM t1
) AS X
Which results in something like the following:
+---------+---------+
| Weekday | DayType |
+---------+---------+
| 2 | Weekend |
| 0 | Weekday |
| 2 | Weekday |
| 0 | Weekend |
| 10 | Weekday |
+---------+---------+
I don't see any rhyme or reason as to what the numbers are under the 'Weekday' column, I suspect they're being grouped somehow. And of course there are several other columns missing, but since I can't put a large scope in the outer query with this as inner one, I can't figure out how to pull those in. Help is greatly appreciated.
It looks like you want to union all a pair of aggregation queries that use sum() and group by id, time, one for Weekday and one for Weekend:
select Id, DayType = 'Weekend', [time], Tasks=sum(Weekend)
from t
group by id, [time]
union all
select Id, DayType = 'Weekday', [time], Tasks=sum(Weekday)
from t
group by id, [time]
Try with this
select ID, 'Weekday' as DayType, Time, sum(Weekday)
from t1
group by ID, Time
union all
select ID, 'Weekend', Time, sum(Weekend)
from t1
group by ID, Time
order by order by 1, 3, 2
Not tested, but it should do the trick. It may require 2 proc sql steps for the calculation, one for summing and one for the case when statements. If you have extra lines, just use a max statement and group by ID, Time, type_day.
Proc sql; create table want as select ID, Time,
sum(weekday) as weekdayTask,
sum(weekend) as weekendTask,
case when calculated weekdaytask>0 then weekdaytask
when calculated weekendtask>0 then weekendtask else .
end as Task,
case when calculated weekdaytask>0 then "Weekday"
when calculated weekendtask>0 then "Weekend"
end as Day_Type
from have
group by ID, Time
;quit;
Proc sql; create table want2 as select ID, Time, Day_Type, Task
from want
;quit;

ASP.NET Join duplicate results into one and sum other fields

Currently I have the following table in database dbo.test :
agentid | serv | func | com |
--------+------+------+-----|
ampg | 1 | 0 | 1 |
jrep | 0 | 0 | 1 |
ampg | 1 | 1 | 0 |
jrep | 1 | 0 | 1 |
Desired result:
agentid | serv | func | com |
--------+------+------+-----|
ampg | 2 | 1 | 1 |
jrep | 1 | 0 | 2 |
So it recognizes same agent id and combines into one row summing up the values of each other column. I will then present it in gridview in visual. Is it possible?
Thank you
Try this:
select agentid ,sum(serv) as [serv], sum(func) as [func], sum(com) as [com]
from tablename
group by agentid
SQL Group By:
http://www.w3schools.com/sql/sql_groupby.asp
select
agentid,
sum(serv) [sum_serv],
sum(func) [sum_func],
sum(com) [sum_com]
from [table]
group by agentid

Select a column's data in a group and place in new column across entire group

I would like to select a column's data in a group and place that data in its own column for each row of the group.
Specifically, if I've got a table that looks like this:
SELECT * FROM Jobtable
JOBNum | ReqDateTime | RowNum
-------+----------+------
M210 | 2015-01-08 17:01:56.000 | 1
M214 | 2015-01-12 17:46:09.000 | 1
M214 | 2015-01-16 20:19:43.000 | 2
M219 | 2015-01-27 15:05:16.000 | 1
M219 | 2015-01-28 02:01:13.000 | 2
I want to show this:
JOBNum | ReqDateTime | FirstDateInEachGroup | Row |
-------+-------------------------+-------------------------+-----+
M210 | 2015-01-08 17:01:56.000 | 2015-01-08 17:01:56.000 | 1 |
M214 | 2015-01-12 17:46:09.000 | 2015-01-12 17:46:09.000 | 1 |
M214 | 2015-01-16 20:19:43.000 | 2015-01-12 17:46:09.000 | 2 |
M219 | 2015-01-27 15:05:16.000 | 2015-01-27 15:05:16.000 | 1 |
M219 | 2015-01-28 02:01:13.000 | 2015-01-27 15:05:16.000 | 2 |
I want create another column "FirstDateInEachGroup" on the fly which consists of the ReqDateTime which is in each JobNum group with the Row = 1. In the above example you can see that where there are two JobNum's that are the same they have a different "Row", andthe FirstDateInEachGroup would contain the same data in each row with the same JobNum.
How do I do this without using a cursor or function?
Thank you!
I think you want something like this:
SELECT
JobNum, ReqDateTime, RowNum,
(select min(ReqDateTime) from JobTable jt2 where jt2.JobNum = jt1.JobNum group by JobNum) as FirstDateInEachGroup
FROM Jobtable jt1
Just use the min() window function:
SELECT JobNum, ReqDateTime,
MIN(ReqDateTime) OVER (PARTITION BY JobNum) as FirstDateInEachGroup,
RowNum
FROM Jobtable;