SQL and JPQL query - searching all records grouping by parameter with the given date - sql

I have table which looks similar to this:
I want to build query for searching all records from this table with the given date (let's say 5.12.2019) and with earlier dates but group by materialID.
Example: select all materials with date 6.12.2019 should show all materials with this date (or materials with earlier dates) group by material id with the biggest date Result should look like this:
Problem: I want to group my results by MaterialID with the biggest date. So in this example I don't want to show materials with the same id with earlier dates.
For the same example:
Question: How to build query like this using SQL and also JPQL? Because i would like to use this query in Hibernate so i need also JPQL query.
Thanks for your help.

This is a special case of a "top N per category" query. You want to show the maximum date per material id. In SQL (would also work in JPQL):
SELECT SUM(Amount), SUM(Price), MaterialId, MAX(Date)
FROM t
GROUP BY MaterialId
Note that with this technique, you cannot also display the ID, or MAX(ID), as the IDs and dates are not necessarily both monotonously increasing. If you still want the ID displayed as in your example, then write this SQL query (I don't think this can be done in JPQL):
SELECT MAX(ID), SUM(Amount), SUM(Price), MaterialId, MAX(Date)
FROM (
SELECT last_value(ID) OVER (
PARTITION BY MaterialId
ORDER BY Date, ID
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS ID,
Amount,
Price,
MaterialId,
SELECT last_value(Date) OVER (
PARTITION BY MaterialId
ORDER BY Date, ID
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
) AS Date
FROM t
) t
GROUP BY MaterialId

Related

PostgreSQL backward intersection & join

I have a survey form of certain questions for a certain facility.
the facility can be monitored(data entry) more than once in a month.
now i need the latest data(values) against the questions
but if there is no latest data against any question i will traverse through prior records(previous dates) of the same month.
i can get the latest record but i don't know how to get previous record of the same month id there is no latest data.
i am using PostgreSQL 10.
Table Structure is
Desired output is
You can try to use ROW_NUMBER window function to make it.
SELECT to_char(date, 'MON') month,
facility,
idquestion,
value
FROM (
SELECT *,ROW_NUMBER() OVER(PARTITION BY facility,idquestion ORDER BY DATE DESC) rn
FROM T
) t1
where rn = 1
demo:db<>fiddle
SELECT DISTINCT
to_char(qdate, 'MON'),
facility,
idquestion,
first_value(value) OVER (PARTITION BY facility, idquestion ORDER BY qdate DESC) as value
FROM questions
ORDER BY facility, idquestion
Using window functions:
first_value(value) OVER ... gives you the first value of a window frame. The frame is a group of facility and idquestion. Within this group the rows are ordered by date DESC. So the very last value is first no matter which date it is
DISTINCT filtered the tied values (e.g. there are two values for facility == 1 and idquestion == 7)
Please notice:
"date" is a reserved word in Postgres. I strongly recommend to rename your column to avoid certain trouble. Furthermore in Postgres lower case is used and is recommended.

how to get latest date column records when result should be filtered with unique column name in sql?

I have table as below:
I want write a sql query to get output as below:
the query should select all the records from the table but, when multiple records have same Id column value then it should take only one record having latest Date.
E.g., Here Rudolf id 1211 is present three times in input---in output only one Rudolf record having date 06-12-2010 is selected. same thing with James.
I tried to write a query but it was not succssful. So, please help me to form a query string in sql.
Thanks in advance
You can partition your data over Date Desc and get the first row of each partition
SELECT A.Id, A.Name, A.Place, A.Date FROM (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Date DESC) AS rn
FROM [Table]
) A WHERE A.rn = 1
you can use WITH TIES
select top 1 PERCENT WITH TIES * from t
order by (row_number() over(partition by id order by date desc))
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=280b7412b5c0c04c208f2914b44c7ce3
As i can see from your example, duplicate rows differ only in Date. If it's a case, then simple GROUP BY with MAX aggregate function will do the job for you.
SELECT Id, Name, Place, MAX(Date)
FROM [TABLE_NAME]
GROUP BY Id, Name, Place
Here is working example: http://sqlfiddle.com/#!18/7025e/2

Combining records but other columns have different values

I wanted to combine the same values in CATEGORY in this table, but as you can see the dates in the DATE column do not match up. Is there a way I can ignore this and just take the latest date in SQL?
SELECT CATEGORY, SIDE, sum(QUANTITY),sum(PRICE)
FROM table_name
group by 1,2
Basically, exclude the date column and the category can be grouped easily.
I would suggest something like:
SELECT CATEGORY, SIDE, Sum(QUANTITY) AS TOTALQUANTITY, PRICE, Max(DATE) AS LASTDATE
FROM YourTableName
GROUP BY CATEGORY, SIDE, PRICE

Filtering by analytic function results without subquery or subtable

I'm working on Netsuite project which has limited SQL capabilites. It's difficult to test as I am basically guessing the SQL they are building in their GUI.
I'd like to filter the results of a query to the results with a negative value of a culmative sum.
Is the following a valid PL/SQL construct (barring any small syntactical errors)?
SELECT SUM(amount) OVER(PARTITION BY itemid ORDER BY date ROWS UNBOUNDED
PRECEDING) AS "sum" FROM table WHERE sum < 0
Secondly, due to limitations in Netsuite, is the following a valid construct?
SELECT SUM(amount) OVER(PARTITION BY itemid ORDER BY date ROWS UNBOUNDED
PRECEDING) AS "sum" FROM table WHERE SUM(amount) OVER(PARTITION BY itemid
ORDER BY date ROWS UNBOUNDED PRECEDING) < 0
Oracle's documentation suggests that neither of these are valid and filtering an analytic function should be done via subquery but some google groups and other websites suggest otherwise. Most however are using RANK() and DENSE_RANK() functions in their examples which may function differently.
To filter in on the result of analytic functions you have to use inline views (subqueries in the from clause).
For example, your query might look like:
select *
from (
select itemid,
date,
sum(amount) over (
partition by itemid
order by date
rows between unbounded preceding
and current row
) as run_sum
from table
)
where run_sum < 0
This will show all items, and the associated dates, on which the running sum for that item was less than zero (if there are any such dates for a given item).

Select values with duplicate max values sql

I have a table made up of dates and sales totals for the particular date. I would like to be able to query the table and select the following: max sales, the date associated with the max sale figure, sum of all sales, and the minimum date in the table. One additional complication is that there are duplicate max values. I don't care which max value is chosen but I just want one at random. This is for Oracle.
Here is what I tried. It was using a sub query.
Select sales, date, min(date), sum(sales) from table
Where sales = (select distinct(max(sales)) from table)
select
max(sales),
max(date_) keep (dense_rank first order by sales desc),
sum(sales),
min(date_)
from
table_
See also This SQL Fiddle