Create summary of data in specified format - sql

I have an SQL query which produces the following table:
+----------------------+-------+------+------+-----+------+
| PAYCODE | HOURS | COST | FROM | TO | ROLE |
+----------------------+-------+------+------+-----+------+
| EU All Paid Time | 5 | 66.5 | 583 | 471 | ASSC |
| DE Basic P | 5 | 66.5 | 583 | 471 | ASSC |
| EU All Hours Average | 4 | 53.2 | 583 | 470 | ASSC |
| EU All Hours Average | 5 | 66.5 | 583 | 471 | ASSC |
| EU All Worked TIme | 5 | 66.5 | 583 | 471 | ASSC |
| DE Basic P | 4 | 53.2 | 583 | 470 | ASSC |
| EU All Paid Time | 4 | 53.2 | 583 | 470 | ASSC |
| EU All Regular | 4 | 53.2 | 583 | 470 | ASSC |
| EU All Regular | 5 | 66.5 | 583 | 471 | ASSC |
| EU All Worked TIme | 4 | 53.2 | 583 | 470 | ASSC |
+----------------------+-------+------+------+-----+------+
I want to change the way it looks so that I have the From, To and Role columns as-is on the left, then the paycode names across the column headers with hours underneath, then another set of columns with paycode names across the column headers with costs underneath
How can this be done? I managed to do separate tables of hours/costs using PIVOT, but want the combined view I describe instead.
IT's worth noting that the paycode list will vary depending on what ones are earnt so I don't want to fix the names using a standard pivot

Related

What's the shortest method to generate a column of numbers for queries instead of having to count each rows in SQL?

I'm going through some practice questions and had a question asking for number of rows shown as the result of my query and found myself counting each rows for it and thought it was inefficient.
How do I create a new column that numbers the rows from 1 to number of rows?
If my query is as follows,
SELECT *
FROM invoices
WHERE BillingCountry = 'Germany' AND Total > 5
then the result is:
+-----------+------------+---------------------+-------------------------+-------------+--------------+----------------+-------------------+-------+
| InvoiceId | CustomerId | InvoiceDate | BillingAddress | BillingCity | BillingState | BillingCountry | BillingPostalCode | Total |
+-----------+------------+---------------------+-------------------------+-------------+--------------+----------------+-------------------+-------+
| 12 | 2 | 2009-02-11 00:00:00 | Theodor-Heuss-Straße 34 | Stuttgart | None | Germany | 70174 | 13.86 |
| 40 | 36 | 2009-06-15 00:00:00 | Tauentzienstraße 8 | Berlin | None | Germany | 10789 | 13.86 |
| 52 | 38 | 2009-08-08 00:00:00 | Barbarossastraße 19 | Berlin | None | Germany | 10779 | 5.94 |
| 67 | 2 | 2009-10-12 00:00:00 | Theodor-Heuss-Straße 34 | Stuttgart | None | Germany | 70174 | 8.91 |
| 95 | 36 | 2010-02-13 00:00:00 | Tauentzienstraße 8 | Berlin | None | Germany | 10789 | 8.91 |
| 138 | 37 | 2010-08-23 00:00:00 | Berger Straße 10 | Frankfurt | None | Germany | 60316 | 13.86 |
| 193 | 37 | 2011-04-23 00:00:00 | Berger Straße 10 | Frankfurt | None | Germany | 60316 | 14.91 |
| 236 | 38 | 2011-10-31 00:00:00 | Barbarossastraße 19 | Berlin | None | Germany | 10779 | 13.86 |
| 241 | 2 | 2011-11-23 00:00:00 | Theodor-Heuss-Straße 34 | Stuttgart | None | Germany | 70174 | 5.94 |
| 269 | 36 | 2012-03-26 00:00:00 | Tauentzienstraße 8 | Berlin | None | Germany | 10789 | 5.94 |
| 291 | 38 | 2012-06-30 00:00:00 | Barbarossastraße 19 | Berlin | None | Germany | 10779 | 8.91 |
| 367 | 37 | 2013-06-03 00:00:00 | Berger Straße 10 | Frankfurt | None | Germany | 60316 | 5.94 |
+-----------+------------+---------------------+-------------------------+-------------+--------------+----------------+-------------------+-------+
There are 12 rows of information pulled from a dataset, but I only realized it after manually counting the rows.
What can I add in my query that can add a column in the left-most side of the result that shows numbers 1 through 12 for each rows like how Excel would show it as and is there a way to do the same for the columns but in an alphabetical order?
I would use ROW_NUMBER function:
SELECT ROW_NUMBER() OVER (ORDER BY BillingAddress, BillingCity) AS RN, *
FROM invoices
WHERE BillingCountry = 'Germany' AND Total > 5

Average by day using timestamp

I have the following mariadb table. The data is added 3 times per day. I am looking to write a SQL query that would give me the average amount for the day. This way I can say on May 13 'serender' averaged x amt, 'shilta' averaged x amt and 'snowq' averaged x amt. On May 14th the averages were... and so on for each date.
key | timestamp | card | amt |
-------------------------------------------
| 126 | 1620837006 | serender | 8040 |
| 127 | 1620837006 | shilta | 752 |
| 128 | 1620837006 | snowq | 308 |
| 132 | 1620862207 | serender | 846 |
| 133 | 1620862207 | shilta | 803 |
| 134 | 1620862207 | snowq | 759 |
| 139 | 1620894616 | serender | 845 |
| 140 | 1620894616 | shilta | 805 |
| 141 | 1620894616 | snowq | 759 |
| 146 | 1620923404 | serender | 869 |
| 147 | 1620923404 | shilta | 804 |
| 148 | 1620923404 | snowq | 759 |
| 153 | 1620948607 | serender | 755 |
| 154 | 1620948607 | shilta | 650 |
| 155 | 1620948607 | snowq | 530 |
If you want to see the date then convert it from a Unix timestamp to a date:
select date(from_unixtime(timstamp)) as dte, card, avg(amt)
from t
group by dte, card;

INSERT INTO target table new entry for each column within a row of source table

I'm sorry if the title is confusing. I have a very large source table that is structured somewhat like this
From Mile | To Mile |
| |From Weight| 1000 | 1100 | 1200 | 1300... | 22500 | 23000
| |To Weight | 1099 | 1199 | 1299 | 1499... | 22999 | 23499
==========================================================================
1 | 20 | | 1500 | 1505 | 1489 | 1854... | 3400 | 2990
------------------------------------------------------------------------
21 | 40 | | 1400 | 1705 | 491 | 5581... | 1600 | 2989
------------------------------------------------------------------------
41 | 60 | | 1800 | 1635 | 1982 | 1888... | 3200 | 3480
------------------------------------------------------------------------
Where one can pick a certain milage, e.g. 23, and a certain weight, e.g. 1250, and get a "rate" - in this case, 491.
From Mile | To Mile |
| |From Weight| | | 1200 | | |
| |To Weight | | | 1299 | | |
==========================================================================
| | | | | | ... | |
------------------------------------------------------------------------
21 | 40 | | | | 491 | ... | |
------------------------------------------------------------------------
| | | | | | ... | |
------------------------------------------------------------------------
I would want to insert each rate with their corresponding weight and mile ranges.
Id | Mile_To | Mile_From | Weight_To | Weight_From | Rate
===========================================================
0 | 1 | 20 | 1000 | 1099 | 1500
-----------------------------------------------------------
1 | 1 | 20 | 1100 | 1199 | 1505
-----------------------------------------------------------
2 | 1 | 20 | 1200 | 1299 | 1389
-----------------------------------------------------------
3 | 1 | 20 | 1300 | 1499 | 1854
-----------------------------------------------------------
...
-----------------------------------------------------------
40 | 1 | 20 | 22500 | 22999 | 3400
-----------------------------------------------------------
41 | 1 | 20 | 23000 | 23499 | 2990
-----------------------------------------------------------
42 | 21 | 40 | 1000 | 1199 | 1400
What is the best way to step through the source table and insert the data as formatted above? There around hundreds of rows and columns, so naming each one would be similar to manually entering the data.
Here is a SQLFiddle with an example of the source table: http://sqlfiddle.com/#!18/48777a/1
You can use cross apply to unpivot this dataset:
select
s.from_miles,
s.to_miles,
x.*
from source s
cross apply (values
(1000, 1099, s.[1000_to_1099]),
(1100, 1199, s.[1100_to_1199]),
(1200, 1299, s.[1200_to_1299]),
(1300, 1399, s.[1300_to_1399]),
(1400, 1499, s.[1400_to_1499])
) as x(weight_from, weigh_to, rate)
You can easily turn this to an insert statement:
insert into newtable (from_moles, to_moles, weight_from, weight_to, rate)
select ... -- above query

How to add total sum of each rows within group with DAX Power BI

I am trying to give rank column of every group which repeating in every rows within the group of the original table but not the shape of after sum-up.
The formula i found in another site but it show an error :
https://intellipaat.com/community/9734/rank-categories-by-sum-power-bi
Table1
+-----------+------------+-------+
| product | date | sales |
+-----------+------------+-------+
| coffee | 11/03/2019 | 15 |
| coffee | 12/03/2019 | 10 |
| coffee | 13/03/2019 | 28 |
| coffee | 14/03/2019 | 1 |
| tea | 11/03/2019 | 5 |
| tea | 12/03/2019 | 2 |
| tea | 13/03/2019 | 6 |
| tea | 14/03/2019 | 7 |
| Chocolate | 11/03/2019 | 30 |
| Chocolate | 11/03/2019 | 4 |
| Chocolate | 11/03/2019 | 15 |
| Chocolate | 11/03/2019 | 10 |
+-----------+------------+-------+
The Goal
+-----------+------------+-------+-----+------+
| product | date | sales | sum | rank |
+-----------+------------+-------+-----+------+
| coffee | 11/03/2019 | 15 | 54 | 5 |
| coffee | 12/03/2019 | 10 | 54 | 5 |
| coffee | 13/03/2019 | 28 | 54 | 5 |
| coffee | 14/03/2019 | 1 | 54 | 5 |
| tea | 11/03/2019 | 5 | 20 | 9 |
| tea | 12/03/2019 | 2 | 20 | 9 |
| tea | 13/03/2019 | 6 | 20 | 9 |
| tea | 14/03/2019 | 7 | 20 | 9 |
| Chocolate | 11/03/2019 | 30 | 59 | 1 |
| Chocolate | 11/03/2019 | 4 | 59 | 1 |
| Chocolate | 11/03/2019 | 15 | 59 | 1 |
| Chocolate | 11/03/2019 | 10 | 59 | 1 |
+-----------+------------+-------+-----+------+
The script
sum =
SUMX(
FILTER(
Table1;
Table1[product] = EARLIER(Table1[product])
);
Table1[sales]
)
The Error :
EARLIER(Table1[product]) # Parameter is not correct type cannot find name 'product'
What's wrong with the script above ?
* not able to test this script:
rank = RANKX( ALL(Table1); Table1[sum]; ;; "Dense" )
before fixed the sum approach
The script is designed for a calculated column, not a measure. If you enter it as a measure, EARLIER has no "previous" row context to refer to, and gives you the error.
Create a measure:
Total Sales = SUM(Table1[sales])
This measure will be used to show sales.
Create another measure:
Sales by Product =
SUMX(
VALUES(Table1[product]);
CALCULATE([Total Sales]; ALL(Table1[date]))
)
This measure will show sales by product ignoring dates.
Third measure:
Sale Rank =
RANKX(
ALL(Table1[product]; Table1[date]);
[Sales by Product];;DESC;Dense)
Create a report with product and dates on a pivot, and drop all 3 measures into it. Result:
Tweak RANKX parameters to change the ranking mode, if necessary.

How to calculate running total in SQL

I have my dataset in the given format
It's a month level data along with salary for each month.
I need to calculate cumulative salary for each month end. How can I do this
+----------+-------+--------+---------------+
| Account | Month | Salary | Running Total |
+----------+-------+--------+---------------+
| a | 1 | 586 | 586 |
| a | 2 | 928 | 1514 |
| a | 3 | 726 | 2240 |
| a | 4 | 538 | 538 |
| b | 1 | 956 | 1494 |
| b | 3 | 667 | 2161 |
| b | 4 | 841 | 3002 |
| c | 1 | 826 | 826 |
| c | 2 | 558 | 1384 |
| c | 3 | 558 | 1972 |
| c | 4 | 735 | 2707 |
| c | 5 | 691 | 3398 |
| d | 1 | 670 | 670 |
| d | 4 | 838 | 1508 |
| d | 5 | 1000 | 2508 |
+----------+-------+--------+---------------+
I need to calculate running total column which is cumulative column. How can I do efficiently in SQL?
You can use SUM with ORDER BY clause inside the OVER clause:
SELECT Account, Month, Salary,
SUM(Salary) OVER (PARTITION BY Account ORDER BY Month) AS RunningTotal
FROM mytable