I want to break the quarters into months. In source I have 2019Q1 but I need to break the one record into 3 records
empid Quarter earnings
-----------------------
123 2019Q1 4000
456 2019Q2 6000
Desired result:
mpid Month earnings
---------------------------
123 January 2019 4000
123 February 2019 4000
123 March 2019 4000
456 April 2019 6000
456 May 2019 6000
456 June 2019 6000
As Larnu suggested, a Calendar Table is well worth the effort. That said, here is an option that performs a 1-to-many join to an ad-hoc table
Example
Select empid
,MonthYear = datename(month,datefromparts(left(Quarter,4),MM,1))+' '+left(Quarter,4)
,Earnings
From YourTable A
Join (
Select *
From ( values (1,1)
,(1,2)
,(1,3)
,(2,4)
,(2,5)
,(2,6)
,(3,7)
,(3,8)
,(3,9)
,(4,10)
,(4,11)
,(4,12)
)B1(QQ,MM)
) B on right(Quarter,1)=QQ
Results
empid MonthYear Earnings
123 January 2019 4000
123 February 2019 4000
123 March 2019 4000
456 April 2019 6000
456 May 2019 6000
456 June 2019 6000
If you don't need the "earnings" value by month, then you just need to setup a CTE to match the Q# with the corresponding months and add that to your query.
Related
looking for most efficient query to sum the cost by customer for both months - there are two tables, one for Jan and one for Feb.
Would I do an inner join or a proc sql? Looking for help. Thanks!
Added an image above because columns didn't stay in order when i typed below.
desired result:
cust 1 total from both tables
cust 2 total from both tables
cust 3 total from both tables
mo cust $ item
jan cust1 10 shoe
jan cust1 20 coat
jan cust1 30 misc
jan cust2 11 shoe
jan cust2 22 top
jan cust3 30 jean
mo cust $ item
feb cust1 15 misc
feb cust1 20 misc
feb cust1 25 jean
feb cust2 35 jean
feb cust3 12 top
feb cust3 30 top
Can only be as efficient as your table deign. I assume "$" isn't the actual column name:
select
cust, sum(dollars) as dollars
from (
select cust, dollars from table1
UNION ALL
select cust, dollars from table2
) d
group by
cust
I have an employee table with below details
EMPid TimeIn. TimeOut
---------------------------------------------
123 1 Jan 2016 10:10 NULL
123 NULL 1 Jan 2016 18:30
123 1 Jan 2016 9:10 NULL
123 NULL 1 Jan 2016 18:00
I need output with order by time in ascending order. Below is sample output.
EMPid TimeIn. TimeOut
------------------------------------------------
123 1 Jan 2016 9:10 NULL
123 1 Jan 2016 10:10 NULL
123 NULL 1 Jan 2016 18:00
123 NULL 1 Jan 2016 18:30
SELECT * FROM Employee ORDER BY TimeIn, TimeOut
Try this,
DECLARE #employee TABLE (EMPid INT,TimeIn DATETIME,TimeOut DATETIME)
INSERT INTO #employee(EMPid,TimeIn,TimeOut)
VALUES(123,' 1 Jan 2016 10:10', NULL),
(123,NULL, '1 Jan 2016 18:30'),
(123,' 1 Jan 2016 9:10' , NULL),
(123, NULL , '1 Jan 2016 18:00')
SELECT * FROM #employee ORDER BY ISNULL(TimeIn,TimeOut)
I have a table, an example shown below, that lists people and their birth and death years (9999 indicates an alive person).
person | born | died
1 | 2001 | 9999
2 | 2002 | 2003
3 | 2002 | 2008
4 | 2004 | 2009
5 | 2005 | 9999
6 | 2010 | 2012
I want to compute the population over the years. For the example shown above, the output is going to be the following. The list of persons alive at the end of the rows is for demonstration purposes only, I don't need that in my output.
year | population
2001 | 1 (1)
2002 | 3 (1,2,3)
2003 | 2 (1,3)
2004 | 3 (1,3,4)
2005 | 4 (1,3,4,5)
2006 | 4 (1,3,4,5)
2007 | 4 (1,3,4,5)
2008 | 3 (1,4,5)
2009 | 2 (1,5)
2010 | 3 (1,5,6)
2011 | 3 (1,5,6)
2012 | 2 (1,5)
I am able to get this writing a C# program and looping through each of the rows in the original table and incrementing the population count of each of the years that fall between the birth and death years. However, I need to do it entirely in a TSQL script. I am a TSQL newbie. How do I go about it? If a similar problem has already been discussed, please point me to it. Thank you.
DECLARE #t TABLE(person INT, born INT, died INT);
INSERT #t VALUES
(1,2001,9999),
(2,2002,2003),
(3,2002,2008),
(4,2004,2009),
(5,2005,9999),
(6,2010,2012);
DECLARE #start INT, #end INT;
SELECT #start = 2001, #end = 2012;
;WITH n(y) AS
(
SELECT TOP (#end - #start + 1)
#start - 1 + ROW_NUMBER() OVER (ORDER BY [object_id])
FROM sys.all_objects
)
SELECT
[year] = n.y,
population = SUM(CASE WHEN n.y >= t.born AND n.y < t.died THEN 1 ELSE 0 END)
FROM n CROSS JOIN #t AS t GROUP BY n.y;
Results:
year population
---- ----
2001 1
2002 3
2003 2
2004 3
2005 4
2006 4
2007 4
2008 3
2009 2
2010 3
2011 3
2012 2
FWIW I just started a blog series on this very thing:
http://www.sqlperformance.com/2013/01/t-sql-queries/generate-a-set-1
i need a query to find the date based on year, month, day of the week and weekday number. Say for example, if the question is to find the date of 2nd Sunday of January 2010, the answer should be '2010-01-10'.
Inputs are
Yr | Mon | Dy | Dyno
-----------------------
2010 | Jan | Sun | 2
2005 | Jan | Mon | 3
1995 | Feb | Sun | 1
2000 | Feb | Wed | 4
1982 | Mar | Tue | 2
2010 | Mar | Tue | 8
Dyno states dayno
The easiest answer to many date-related questions in SQL is to create a calendar table. In your case, if you create a table with the columns you've already shown, and an extra one with the DATETIME value that you want (call it BaseDate), you can get the value you need with a simple query:
select BaseDate
from dbo.Calendar
where Yr = 2010 and Mon = 'Jan' and Dy = 'Sunday' and Dyno = 2
Of course, your calendar table can have 10, 20 or more columns, depending on what values you find useful for your queries.
I have table that has a column of type DateTime, I would like to pivot on the datetime column so that the dates are displayed as columns (as days of the week Monday, Tuesday etc).
So for example I have a table like this (can't remember how SQL Server displays full datetimes but you get the idea):
BugNo | DateOpened | TimeSpent
1234 | 16/08/2010 | 1.0
4321 | 16/08/2010 | 3.5
9876 | 17/08/2010 | 1.5
6789 | 18/08/2010 | 7.0
6789 | 19/08/2010 | 6.5
6789 | 20/08/2010 | 2.5
I would like to pivot on the DateOpened column to create a result set like this
|TimeSpentOnBugByDay| Mon | Tue | Wed | Thu | Fri | Sat | Sun
1234 1
4321 3.5
9876 1.5
6789 7.0
6789 6.5
6789 2.5
I should point out that I'll only be retrieving one week at a time.
I'm not sure if this is possible, though I'm pretty certain I have seen something like this before (that I didn't write).
You can do this
SELECT BugNo, [Monday], [Tuesday], [Wednesday], [Thursday], [Friday], [Saturday], [Sunday]
FROM (
SELECT BugNo, DATENAME(dw, DateOpened) AS DayWeek, TimeSpent
FROM Bugs
) AS src
pivot (
SUM(TimeSpent) FOR DayWeek IN ([Monday], [Tuesday], [Wednesday], [Thursday], [Friday], [Saturday], [Sunday])
) AS pvt