I have a problem trying to make an alias for new column and using it in GROUP BY clause:
SELECT TOP 100 Percent
count(id) AS [items_by_day],
(SELECT DATEADD(dd, 0, DATEDIFF(dd, 0, [date]))) AS [date_part]
FROM [MyDB].[dbo].[MyTable]
GROUP BY DAY([date]), MONTH([date]), YEAR([date]), date_part
I get the following error:
Msg 207, Level 16, State 1, Line 5
Invalid column name 'date_part'.
How is it possible to solve the problem?
How about a subquery?
See my demo at sqlfiddle
Select Count(*) as nrOfRecords, sq.[items_by_day], sq.[date_part]
From (
SELECT TOP 100 Percent count(id) AS [items_by_day]
,(Select Dateadd(dd, 0, Datediff(dd, 0, [date]))) AS [date_part]
From [MyTable]
Group By id, date
) as sq
Group by sq.[items_by_day], sq.[date_part]
The part (SELECT DateAdd(... DateDiff(...)) seems to return the plain date. Can you explain what i am missing?
You cannot use a column alias in a GROUP BY, aliases are for display, unless when the alias is in a subquery, in this case , it becomes the column name.
Related
I have date in yyyymmdd format in an int column and I would like to group by month i.e. yyyymm.I've tried the below two versions
select to_char(to_timestamp(create_dt),'YYYYMM'),count(*) from table_name
group by to_char(to_timestamp(create_dt),'YYYYMM')
order by to_char(to_timestamp(create_dt),'YYYYMM') desc
AND
select to_char(create_dt,'YYYYMM'),count(*) from table_name
group by to_char(create_dt,'YYYYMM')
order by to_char(create_dt,'YYYYMM') desc
select create_dt / 100, count(*)
from t
group by 1
order by 1 desc
limit 6
Figured it out,any alternate ways would be helpful.
select substring(create_dt::int8,1,6),count(*) from table
group by substring(create_dt::int8,1,6)
order by substring(create_dt::int8,1,6) desc
limit 6;
Version: SQL Server 2014
Objective: Create a complete time series with existing date range records.
Initial Data Setup:
IF OBJECT_ID('tempdb..#DataSet') IS NOT NULL
DROP TABLE #DataSet;
CREATE TABLE #DataSet (
RowID INT
,StartDt DATETIME
,EndDt DATETIME
,Col1 FLOAT);
INSERT INTO #DataSet (
RowID
,StartDt
,EndDt
,Col1)
VALUES
(1234,'1/1/2016','12/31/2999',100)
,(1234,'7/23/2016','7/27/2016',90)
,(1234,'7/26/2016','7/31/2016',80)
,(1234,'10/1/2016','12/31/2999',75);
Desired Results:
RowID, StartDt, EndDt, Col1
1234, '01/01/2016', '07/22/2016', 100
1234, '07/23/2016', '07/26/2016', 90
1234, '07/26/2016', '07/31/2016', 80
1234, '08/01/2016', '09/30/2016', 100
1234, '10/01/2016', '12/31/2999', 75
Not an easy task I will admit, If anyone has a suggestion on how to tackle this utilizing SQL alone (Microsoft 2014 TSQL) I would greatly appreciate it. Please keep in mind it is SQL and we want to try to avoid cursors at all costs based on performance for large data sets.
Thanks in Advance.
Also as an FYI I was able to achieve half of this by utilizing a LEAD windows function to set the End Date of the current record to the Startdate-1 of the next. The other half of filling gaps back in from previous records still eludes me.
Updated for the 9/31 to 9/30 date.
The following query does essentially what you are asking. You can tweak it to fit your requirements. Note that when checking the results of my query, your desired results contain 09/31/2016 which is not a valid date.
WITH
RankedData AS
(
SELECT RowID, StartDt, EndDt, Col1,
DATEADD(day, -1, StartDt) AS PrevEndDt,
RANK() OVER(ORDER BY StartDt, EndDt, RowID) AS rank_no
FROM #DataSet
),
HasGapsData AS
(
SELECT a.RowID, a.StartDt,
CASE WHEN b.PrevEndDt <= a.EndDt THEN b.PrevEndDt ELSE a.EndDt END AS EndDt,
a.Col1, a.rank_no
FROM RankedData a
LEFT JOIN RankedData b ON a.rank_no = b.rank_no - 1
)
SELECT RowID, StartDt, EndDt, Col1
FROM HasGapsData
UNION ALL
SELECT a.RowID,
DATEADD(day, 1, a.EndDt) AS StartDt,
DATEADD(day, -1, b.StartDt) AS EndDt,
a.Col1
FROM HasGapsData a
INNER JOIN HasGapsData b ON a.rank_no = b.rank_no - 1
WHERE DATEDIFF(day, a.EndDt, b.StartDt) > 1
ORDER BY StartDt, EndDt;
I have logic to calculate the sum of receipt amount and receipt date. I am not sure whether the below t-sql works fine for my logic.
I need the max of receipt date and will go for any receipt date ie., 01-01-2014 this should give me the advance amount paid for the person id. Also if the max receipt date value is negative then I need to remove that from the calculation.
WITH rec_cte (amt,recdate) AS
(
select -40, 01-04-2014 UNION ALL
select -40,01-04-2014 UNION ALL
select 40,20-04-2013 UNION ALL
select -20,10-04-2012 UNION ALL
select 50,20-04-2011 UNION ALL
select 40,20-04-2010 UNION ALL
)
SELECT SUM(amt),recdate from rec_cte
As far as I am able to interpret your question, you are looking for SUM(amt) based on ID.
WITH rec_cte AS
(
select 1 as id,-40 as amt, '01-04-2014' as recdate UNION ALL
select 1, -40,'01-04-2014' UNION ALL
select 2, 40,'20-04-2013' UNION ALL
select 3, -20,'10-04-2012' UNION ALL
select 2, 50,'20-04-2011' UNION ALL
select 1, 40,'20-04-2010'
)
SELECT id, SUM(amt) from rec_cte
--where recdate= '01-04-2014'
group by id
having SUM(amt)>=0
I have a question, although I can't really go into specifics.
Will the following query:
SELECT DISTINCT tableOuter.Property, (SELECT COUNT(ID) FROM table AS tableInner WHERE tableInner.Property = tableOuter.Property)
FROM table AS tableOuter
WHERE tableOuter.DateTime > DATEADD(year, -1, GETDATE())
AND tableOuter.Property IN (
...
)
Select one instance of each property in the IN clause, together with how often a row with that property occured in the last year?
I just read up on Correlated Subqueries on MSDN, but am not sure if I got it right.
If i understand you corrrecly, you want to get all occurences of each Property in the last year, am i right?
Then use GROUP BY with a HAVING clause:
SELECT tableOuter.Property, COUNT(*) AS Count
FROM table AS tableOuter
GROUP BY tableOuter.Property
HAVING tableOuter.DateTime > DATEADD(year, -1, GETDATE())
AND tableOuter.Property IN ( .... )
First time posting here, a newbie to SQl, and I'm not exactly sure how to word this but I'll try my best.
I have a query:
select report_month, employee_id, split_bonus,sum(salary) FROM empsal
where report_month IN('2010-12-01','2010-11-01','2010-07-01','2010-04-01','2010-09-01','2010-10-01','2010-08-01')
AND employee_id IN('100','101','102','103','104','105','106','107')
group by report_month, employee_id, split_bonus;
Now, to the result of this query, I want to add a new column split_bonus_cumulative that is essentially equivalent to adding a sum(split_bonus) in the select clause but for this case, the group buy should only have report_month and employee_id.
Can anyone show me how to do this with a single query? Thanks in advance.
Try:
SELECT
report_month,
employee_id,
SUM(split_bonus),
SUM(salary)
FROM
empsal
WHERE
report_month IN('2010-12-01','2010-11-01','2010-07-01','2010-04-01','2010-09-01','2010-10-01','2010-08-01')
AND
employee_id IN('100','101','102','103','104','105','106','107')
GROUP BY
report_month,
employee_id;
Assuming you're using Postgres, you might also find window functions useful:
http://www.postgresql.org/docs/9.0/static/tutorial-window.html
Unless I'm mistaking, you want something that resembles the following:
select report_month, employee_id, salary, split_bonus,
sum(salary) over w as sum_salary,
sum(split_bonus) over w as sum_bonus
from empsal
where ...
window w as (partition by employee_id);
CTEs are also convenient:
http://www.postgresql.org/docs/9.0/static/queries-with.html
WITH
rows as (
SELECT foo.*
FROM foo
WHERE ...
),
report1 as (
SELECT aggregates
FROM rows
WHERE ...
),
report2 as (
SELECT aggregates
FROM rows
WHERE ...
)
SELECT *
FROM report1, report2, ...