How to manage complex sorting in SQL? - sql

I need to have date sorting with the partial dates. I have a table with the following columns.
Day Month Year
-- ---- -----
NULL 03 1990
26 10 1856
03 07 Null
31 NULL 2018
NULL NULL NULL
I have a grid in which One of the column is Date where I am combining the above three columns and displays the dates.
Now I want sorting on this date column in the grid. The sort order of the dates should be like following :
[blank date]
22 [day]
March
April 12
May
July 29
August
September
September 14
October
1948
October 1948
October 1 1948
July 1976
1977
July 1977
July 23 1977
December 1981
December 29 1981
I have tried various ways to achieve this. But I am not able to get the desired result. Following are some of the ways I have applied.
I have tried sorting by creating the stored procedure in which I am creating the whole date by combining 3 columns and converting them in standard date formats and comparing the values. I have also tried by creating the computed property in the model and sorting them accordingly.
How can I do this in SQL?

I think you could do:
order by coalesce(year, '0000'), coalesce(month, '00'), coalesce(day, '')
You can be more explicit, but this puts the NULL values before the other values in the column.
Note: This uses the SQL standard operator for string concatenation. Not all databases support this, so you might need to tweak the code for your database.

Related

Aggregate multiple invoice numbers and invoice amount rows into one row

I have the following:
budget_id
invoice_number
April
June
August
004
11
NULL
690
NULL
004
12
1820
NULL
NULL
004
13
NULL
NULL
890
What I want to do is do the following:
budget_id
invoice_number
April
June
August
004
11, 12, 13
1820
690
890
However, when I try to do the following:
SELECT budget_id,
STRING_AGG(invoice_number, ',') AS invoice number,
April,
June,
August
FROM invoice_table
GROUP BY budget_id,
April,
June,
August
Nothing happens. The table stays exactly the same. The code above works if I'm able to comment out the months as it aggregates the invoices numbers without the months. But once I include the months, I still get 3 separate rows. I need the invoice amounts to be included with the months. Is it possible to get the invoice numbers aggregated as well as the invoice amounts in one row? I'm using Big Query if that helps.
Use below query,
SELECT budget_id,
STRING_AGG(invoice_number, ',') invoice_number,
SUM(April) April,
SUM(June) June,
SUM(August) August
FROM invoice_table
GROUP BY 1;

Replacing Pandas Dataframe Header with Date column but in ascending order

I have a Dataframe of 5k+ rows that looks like this. It has Date column which has Month/Year format. The Date column is in string format.
Name Date Friends
A June 2017 100
A April 2017 45
A March 2016 180
B June 2017 43
B April 2017 23
B March 2016 23
C June 2017 64
C April 2017 643
C March 2016 344
I want to format in the following way, which makes unique values from Date Column into headers. But in the ascending order according to Month/Year.
Name March 2016 April 2017 June 2017
A 180 45 100
B 23 23 43
C 344 643 64
I tried using the Pandas function - Pivot.
df=df.pivot(index='Name',columns='Date',values='Friends')
But this doesn't sort the month/year in ascending order but instead it does in alphabetically order. Also Pivot transforms the dataframe in Stacked format.
Any ideas on how to achieve the desired format?
Something like this,
df['Date']=pd.to_datetime(df['Date'])
df=df.sort_values(['Date'], ascending=False)
df.groupby(['Name', 'Date'], sort=False)['Friends'].sum().unstack('Date')

SSRS: Horizontal alignment on a group

On my dataset I select information from four different years sorted by date and how many subscriptions I had on said date, which looks something like this:
Date Year Subs Day
15/09/2014 2015 57 1
16/09/2014 2015 18 2
17/09/2014 2015 16 3
14/09/2015 2016 10 1
15/09/2015 2016 45 2
16/09/2015 2016 28 3
12/09/2016 2017 32 1
13/09/2016 2017 11 2
14/09/2016 2017 68 3
24/08/2017 2018 23 1
25/08/2017 2018 53 2
26/08/2017 2018 13 3
What I'm trying to do is create an 'Year' Column Group to align them horizontally, but when I do that, this is the result:
result
Expected result:
expected result
Is this achievable in SSRS? I've tried removing the group =(Details), which gives me the desired result, except it only returns one line of information.
Any insight aprreciated.
By default, the Details group causes you to get one row per row in the dataset. In your case, I would suggest grouping the Rows by the Day column and create a column group by Year.
First, create the two groups and add columns inside the column group.
Then, add a row outside and above the Day row group. Place the headings here and then delete the top row. It should look like this:
Now these 4 columns will repeat to the right for each year and you will get rows based on the number of days in your dataset.

Columns to Rows in SQL Server

I have a query returning a table which looks like:
Location | November | December | January | February | March | ... | October |
CT 30 70 80 90 60 30
etc.
and I'd like it to look like:
Location | Month | Value |
CT November 30
CT December 70
CT January 80
...
CT October 30
It looks like an unpivot, but I didn't pivot to get it into that form since the base table has the months as columns (the values are just sums of values grouped by location). I've seen plenty of rows-to-columns questions but I haven't found a good columns-to-rows answer, so I'm hoping someone can help me.
Thanks!
You will want to use the UNPIVOT function. This transforms the values of your columns and turns it into rows:
select location, month, value
from <yourquery here>
unpivot
(
value
for month in (January, February, March, April, May, June, July, August,
September, October, November, December)
) unpiv
See SQL Fiddle with Demo

Teradata Default List

There is this one table which contains the amounts and states that I need. However, this table contains a year information but I want month. For example, in the table it shows information for Kentucky for 2011..and thats it. For California it shows about 5 different years. But I need it to repeat by month.
So if in 2011 Kentucky had 12 total, then I need a query that shows 12 for January, February, May....repeatedly
Right now I get this output with a dumb query I have:
Kentucky 12 January
California 800 January
This is done easily by grouping by State, Quantity and Month
I want to make sure that no matter what the Quantity is, each State has ALL months
Kentucky 12 January
Kentucky 12 February
Kentucky 12 May
California 800 January
California 800 February
California 800 May
Any idea on how to do this with Teradata SQL?
The overall query would look something like this:
SELECT
state_quantities.state,
state_quantities.quantity,
all_months.month_name
FROM state_quantities
CROSS JOIN (
...
) all_months
What goes between the brackets for all_months depends on what you mean by "all months".
If you mean all months that appear in state_quantities irrespective of state (so if you have Kentucky with January, California with February and Florida with May, you'd only get those three months) you could use something like this:
SELECT
month_name
FROM state_quantities
GROUP BY month_name
If you want all 12 months, you would join to a table containing all 12 months. In the absence of that, you could use sys_calendar.calendar (syntax below might be off):
SELECT
CAST(calendar_date AS DATE FORMAT 'MMM') AS month_name
FROM sys_calendar.calendar
GROUP BY month_name