PostgreSQL order by month name on distinction - postgresql

I have this query
SELECT DISTINCT ON (tours.departure.departure_month)
tours.departure.departure_month
FROM tours.departure
But I want to order the distinct months by month name. I've tried this from a similar question to_date(tours.departure.departure_month, 'Month'),
but I cannot get it to work with DISTINCT ON.

What is the column type of departure_month is it date or month names, if its date type column you can try the following:
SELECT DISTINCT ON (tours.departure.departure_month)
tours.departure.departure_month
FROM tours.departure
ORDER BY month(tours.departure.departure_month) DESC;

Related

Column name seems to be use instead of alias in GROUP BY

For a project, I'm looking to get all results group by day.
Here is my query:
SELECT MAX(id) AS id,
SUM(value) AS value,
country,
cast(TO_CHAR(date, 'dd/mm/yyyy') AS DATE) AS date
FROM records
GROUP BY date, country
My problem is that records are not groupped correctly when I use my "date" alias, instead it seems to group by the field name.
Results with group by alias
It works if I use indices instead of alias, but I'd like to have column's name in my result :
SELECT MAX(id) AS id,
SUM(value) AS value,
country,
cast(TO_CHAR(date, 'dd/mm/yyyy') AS DATE) AS date
FROM records
GROUP BY 3, 4
Results with group by indices
Has someone an idea why it works this way?
Quote from the manual
An expression used inside a grouping_element can be an input column name, or the name or ordinal number of an output column (SELECT list item), or an arbitrary expression formed from input-column values. In case of ambiguity, a GROUP BY name will be interpreted as an input-column name rather than an output column name
(emphasis mine)
So the (input) column names always have precedence over column aliases.
The two GROUP BY clauses are not equivalent.
In both, the SELECT clause is:
SELECT
MAX(id) AS id,
SUM(value) AS value,
country,
cast(TO_CHAR(date, 'dd/mm/yyyy') AS DATE) AS date
So the columns will be (id, value, country, date).
The first query groups by date then country:
GROUP BY date, country
The second groups by country then date:
GROUP BY 3, 4
With different hierarchy of GROUP BY you'll get different results, such as what you show.

Find rows which have different attribute value in ONE day for same product. (Postgresql)

can someone help me to write a query?
I have for example columns:
Date
product_key
category_code
In one day I expect to have same category_code for one product, but I want to check this with SQL.
Thank you.
If you want to find the day, the product_key and the category_code that doubles, You should use query like this:
SELECT
date,
product_key,
category_code,
count(1)
FROM your_table
GROUP BY date, product_key, category_code
HAVING count(1) > 1;
You can group your results by date and product, and use count and distinct to find if there is more than one category code for a product. You can then filter rows having more than 1 distinct category in the group.
SELECT
Date, product_key, count(distinct category_code) AS categories
FROM
my_table
GROUP BY
Date, product_key
HAVING
count(distinct category_code) > 1

Produce a row for dates that do not exist in a table [duplicate]

I have a postgresql table userDistributions like this :
user_id, start_date, end_date, project_id, distribution
I need to write a query in which a given date range and user id the output should be the sum of all distributions for every day for that given user.
So the output should be like this for input : '2-2-2012' - '2-4-2012', some user id :
Date SUM(Distribution)
2-2-2012 12
2-3-2012 15
2-4-2012 34
A user has distribution in many projects, so I need to sum the distributions in all projects for each day and output that sum against that day.
My problem is what I should group by against ? If I had a field as date (instead of start_date and end_date), then I could just write something like
select date, SUM(distributions) from userDistributions group by date;
but in this case I am stumped as what to do. Thanks for the help.
Use generate_series to produce your dates, something like this:
select dt.d::date, sum(u.distributions)
from userdistributions u
join generate_series('2012-02-02'::date, '2012-02-04'::date, '1 day') as dt(d)
on dt.d::date between u.start_date and u.end_date
group by dt.d::date
Your date format is ambiguous so I guess while converting it to ISO 8601.
This is much like #mu's answer.
However, to cover days with no matches you should use LEFT JOIN:
SELECT d.d::date, sum(u.distributions) AS dist_sum
FROM generate_series('2012-02-02'::date, '2012-02-04'::date, '1 day') AS d(d)
LEFT JOIN userdistributions u ON d.d::date BETWEEN u.start_date AND u.end_date
GROUP BY 1

Postgres groupby query

I need to group by the product name and by the date.
so from the above example, I am expecting to see the result as below. Is it possible . Can some one help me out please.Thanks!
Maybe I'm missing something in your question, but this is as simple as:
select product_name,
date,
count(*) as cnt
from the_table
group by product_name,
date
order by product_name
Btw: date is a horrible name for a column. First because it's a reserved word but more importantly because it does not document what you store in the column. It could be a "purchase_date", a "sold_date", an "expiry_date", ... ?

How do I order my query by a field and still group by a subset of that field in db2?

Sorry if the title is confusing. Here is the query I have
Select MONTH(DATE(TIMESTAMP)), SUM(FIELD1), SUM(FIELD2) from TABLE WHERE TIMESTAMP BETWEEN '2009-07-26 00:00:00' AND '2010-02-24 23:59:59' GROUP BY MONTH(DATE(TIMESTAMP))
This will let me get the month number out of the query. The problem is that right now it is sorting the months 1,2,3,4.... when it spans two separate years. I need to be able to sort this query by year then month.
If I add "ORDER BY TIMESTAMP" at the end of my query I get this error:
Column TIMESTAMP or expression in SELECT list not valid. SQLCODE=-122
Also I changed the field names for this question to keep it clear the field isn't actually called TIMESTAMP
You need to group by year then month.:
SELECT YEAR(YourField),
Month(YourField),
SUM(Field1),
SUM(Field2)
FROM Table
WHERE...
GROUP BY
YEAR(YourField),
Month(YourField)
ORDER BY
YEAR(YourField),
Month(YourField)