SQL Pivot table for monthly aggregate amount - java

I've not much experience in sql.In my little java program using ucanaccess library I was able to perform some simple queries after creating a simple table (named ReportSales). The table is:
ID DATE PRODUCT SALES FEES
1 2014-10-02 productA 10.000 100
2 2014-09-02 productC 12.000 240
3 2014-09-02 productA 8.000 80
4 2014-11-02 productB 7.000 105
5 2014-08-02 productB 6.000 90
.. .......... ........ ...... ....
.. .......... ........ ...... ....
The last task is to create a pivot table in which I would insert the monthly sales per product. Something like:
PRODUCT AUG SEP OCT NOV
productA 0 8.000 10.000 0
productB 6000 0 0 7000
productC 0 12.000 0 0
And another pivot for monthly fees
My (wrong) attempt is:
SELECT [8] as AUG, [9] as SEP, [10] as OCT, [11] as NOV
FROM
(SELECT SALES,MONTH(DATE)
FROM ReportSales) AS tmp
PIVOT
(
SUM(SALES)
FOR MONTH(DATE) IN ([8], [9], [10], [11])
) AS PivotTable
Does anyone can help me? Thanks in advance

UCanAccess supports Pivot queries, only if they are built in Access, so you have firstly to create a crosstab query using the Access IDE.
Or you may simply create a new query in Access entering directly the following SQL:
TRANSFORM sum(ReportSales.sales) AS SalesCount
SELECT ReportSales.product
FROM ReportSales
GROUP BY ReportSales.product
PIVOT Format([date],"mmm");
Then assuming that you saved the query as query1, you have just to execute, with UCanAccess:
Select * from query1;

Related

How to build a sql query to get 100 rows belonging to weekday(Mon-Fri) from a table using epoch time column

I want query a oracle sql database to get 100(this number can increase 10x) rows belonging to weekday (Mon-Fri) using epoch time column. Query will be executed from a spring boot application. What is the approach for building the logic & query for this requirement?
Consider below table for example. The day for A & B both falls on Thursday(i.e weekday) But C falls on Saturday when the epoch time is converted. (acc to GMT time.).
Hence the output must be the rows A & B.
Name
time_c.
A
1674086400
B
1673481600
C
1673049600
I was checking if the sql TO_CHAR() function can some how be used after converting the epoch time to date but I'm not sure how the filter can be applied within the query.
There are 7 days a week and 1970-01-01 is a Thursday, so if we start counting from 1970-01-01 in 7-day periods (where 1970-01-01 is the 0th day of the week) then the weekends are the 2rd and 3th days (again zero-indexed) of each week.
You can use that to exclude the weekends using only arithmetic:
SELECT *
FROM table_name
WHERE MOD(time_c, 7 * 24 * 60 * 60) < 2 * 24 * 60 * 60
OR MOD(time_c, 7 * 24 * 60 * 60) >= 4 * 24 * 60 * 60
FETCH FIRST 100 ROWS ONLY;
As far as Oracle is concerned, here's one option.
(setting date format just to show what is what; you don't have to do that)
SQL> alter session set nls_date_format = 'dd.mm.yyyy';
Session altered.
Sample data:
SQL> with test (name, time_c) as
2 (select 'A', 1674086400 from dual union all
3 select 'B', 1673481600 from dual union all
4 select 'C', 1673049600 from dual
5 ),
Query converts time_c to a date datatype value (datum column) and - additionally - finds which day it was (the dan column). Then, exclude weekends and fetch as many rows as you want (line #16):
6 temp as
7 (select name, time_c,
8 date '1970-01-01' + time_c / 86400 datum,
9 to_char(date '1970-01-01' + time_c / 86400, 'dy', 'nls_date_language = english') dan
10 from test
11 )
12 select name, time_c, datum, dan
13 from temp
14 where dan not in ('sat', 'sun')
15 order by datum desc
16 fetch first 100 rows only;
N TIME_C DATUM DAN
- ---------- ---------- ------------
A 1674086400 19.01.2023 thu
B 1673481600 12.01.2023 thu
SQL>
That piece of code can be rewritten to a function that returns e.g. refcursor or whatever you find appropriate so that you could use it in your application.

How to calculate Statistics for orders group by year in MYSQL?

Order table.
id
created_date
price
1
2021-09-01
100
2
2021-09-01
50
3
2020-09-01
50
4
2020-09-01
150
5
2019-09-01
100
Order details table:-
id
order_id
product_quantity
1
1
10
2
2
20
3
1
30
4
3
10
5
3
20
6
4
30
7
5
20
So I need a MySQL query to get stats about order count and price and product quantity for each year.
The expected table
year(created_date)
orders_count
product_quantity_in_orders
price
2021
2
60
150
2020
2
60
150
2019
1
20
100
Please try this.
SELECT YEAR(o.created_date) year_created
, COUNT(o.id) orders_count
, SUM(t.product_quantity) product_quantity_in_orders
, SUM(o.price) price
FROM orders o
INNER JOIN (SELECT order_id
, SUM(product_quantity) product_quantity
FROM order_details
GROUP BY order_id) t
ON o.id = t.order_id
GROUP BY YEAR(o.created_date)

Get all results that contain the largest value in table

Let's say I have a very simple table called test:
ID AGE NAME
1 12 Bob
1 13 Bob
2 13 John
3 9 Michael
3 11 Michael
I want to return all results that have the largest AGE in the table. So for this case, the result would be the entities with the age 13:
ID AGE NAME
1 13 Bob
2 13 John
I would think something like this should exist, my thought process would have been the following (even though I know the syntax would not work):
connection.getSqlQuery()
.from(test)
.max(test.age)
.list(test.id, test.age, test.name);
What would be the proper query for this?
You can create a subquery and use it in your where clause:
// Aggregate to get the maximum age
var subQuery = connection.getSqlQuery()
.select(test.age.max())
.from(test);
connection.getSqlQuery()
.from(test)
.where(test.age.eq(subQuery))
.list(test.id, test.age, test.name);
If you use JPA, you can also use var subQuery = JPAExpressions.select(...

Decrement the previous data count, if present sending data is same as previous

Suppose i have list of data(oracle MY_SQL) for example
State RPD Mac_address total_Mac_Online_Count.
26 AA aa:bb:12:cc:ab:aa 1
26 BB aa:bb:12:cc:ab:ab 1
26 CC aa:bb:12:cc:ab:ac 1
26 DD aa:bb:12:cc:ab:ad 1
26 EE aa:bb:12:cc:ab:bb 1
Herewith, I'm sending data like this to db
26 AB aa:bb:12:cc:ab:ac
Mac_address is same as for RPD "CC". Now total_Mac_Online_Count should decrease by one for RPD "CC"
26 CC aa:bb:12:cc:ab:ac 0
and for new data it should add normally like
26 AB aa:bb:12:cc:ab:ac 1
Thanks in advance.
Something like this?
Test case:
SQL> create table mac
2 (state number,
3 rpd varchar2(2),
4 mac_address varchar2(20) constraint uk_mac unique,
5 total_count number
6 );
Table created.
SQL> insert into mac
2 select 26, 'aa', 'aa:bb:12:cc:ab:aa', 1 from dual union
3 select 26, 'bb', 'aa:bb:12:cc:ab:ab', 1 from dual union
4 select 26, 'cc', 'aa:bb:12:cc:ab:ac', 1 from dual;
3 rows created.
A procedure: I'm selecting the whole row into a local variable. As you might get NO_DATA_FOUND, I'm handling it (by doing nothing). If there's a match, I'm subtracting the TOTAL_COUNT column value by 1 for the same MAC address row and inserting the whole new row.
However, it seems that this model supports duplicate MAC addresses. Is that legal? What do you want to do in such cases? For example, if you enter the same MAC address once again? SELECT will return TOO_MANY_ROWS which should be handled. One option is to update only one (which one?) row; or ...?
SQL> create or replace procedure p_mac
2 (par_state in number, par_rpd in varchar2, par_mac_address in varchar2)
3 is
4 l_row mac%rowtype;
5 begin
6 select *
7 into l_row
8 from mac
9 where mac_address = par_mac_address;
10
11 update mac set
12 total_count = total_count - 1
13 where mac_address = par_mac_address;
14
15 insert into mac (state, rpd, mac_address, total_count)
16 values
17 (par_state, par_rpd, par_mac_address, 1);
18 exception
19 when no_data_found then null;
20 end;
21 /
Procedure created.
Testing:
SQL> select * from mac;
STATE RP MAC_ADDRESS TOTAL_COUNT
---------- -- -------------------- -----------
26 aa aa:bb:12:cc:ab:aa 1
26 bb aa:bb:12:cc:ab:ab 1
26 cc aa:bb:12:cc:ab:ac 1
SQL> exec p_mac(26, 'ab', 'aa:bb:12:cc:ab:ac');
PL/SQL procedure successfully completed.
SQL> select * From mac;
STATE RP MAC_ADDRESS TOTAL_COUNT
---------- -- -------------------- -----------
26 aa aa:bb:12:cc:ab:aa 1
26 bb aa:bb:12:cc:ab:ab 1
26 cc aa:bb:12:cc:ab:ac 0
26 ab aa:bb:12:cc:ab:ac 1
SQL>

How to select addtion of two columns of a table through hibernate

Suppose i have a table Student
- ID Name Sub1 Sub2
- 1 Deepika 99 89
- 2 Shubham 78 90
I want my hibernate application to provide me the following result
- ID Name Sub1 Sub2 Total
- 1 Deepika 90 80 170
- 2 Shubham 78 90 168
i.e my sql query is
select id name, sub1, sub2, sub1+sub2 as total
from employee
How can i do this in Hibernate? What changes should i make in my hbm.xml file and bean class?
Using addScalar() you can fetch any additional row than the existing information without changing the xml. For more details refer this documentation
Otherwise you need to change the xml and bean class corresponding to the new table structure.

Categories

Resources