SQLITE sum sales by customer and by year - sqlite

I have a sqlite database with this info
id
pcs
dollars
year
10
25
150
2021
10
20
160
2021
10
22
120
2022
11
12
130
2021
11
10
100
2022
I want to get this
id
pcs2021
dollars2021
pcs2022
dollars2022
10
45
310
22
120
11
12
130
10
100
I got this:
SELECT id, SUM(pcs), SUM(dollars) FROM Table GROUP BY id
But I can't find the way to get the SUM of each year separately.
I tried something like:
SELECT id, (SELECT SUM(pcs) FROM Table WHERE id=id AND year=2021) AS pcs2021, (SELECT SUM(dollars) FROM Table WHERE id=id AND year=2021) AS dollars2021, (SELECT SUM(pcs) FROM Table WHERE id=id AND year=2022) AS pcs2022, (SELECT SUM(dollars) FROM Table WHERE id=id AND year=2022) AS dollars2022, FROM Table GROUP BY id
but it doesn't work.....
Thank you for your help.

Using :-
SELECT id, SUM(pcs) AS pcs2021, SUM(dollars) AS dollars2021 FROM `Table` WHERE year = 2021 GROUP BY id;
results in :-
note the above assumes year is an integer so you may have to enclose the literal in single quotes.
Additional (re comment)
My problem is when I want to put different columns with SUM of values for each year
An issue you are having is that id=id will always be true and thus you will sum all rows, irrespective of the id, for the year and get the result (when the syntax is correct):-
That is id is the id of the sub query when you want to compare against the id currently being processed by the main query.
To do this you can give the main query an alias using the AS clause and then refer to the id of the alias so (where the main query is given the alias of a):-
SELECT
id,
(SELECT sum(pcs) FROM `table` WHERE id=a.id AND year='2021') AS pcs2021,
(SELECT sum(dollars) FROM `table` WHERE id=a.id AND year='2021') AS dollars2021,
(SELECT sum(pcs) FROM `table` WHERE id=a.id AND year='2022') AS pcs2022,
(SELECT sum(dollars) FROM `table` WHERE id=a.id AND year='2022') AS dollars2022
FROM `table` AS a
GROUP BY id
;
The result being :-
Note the use of Table as a table name will result in a syntax error if it is not enclosed as Table is an SQLite keyword.

Related

SQLITE get next row after ORDERBY

I need to get the next row from an ORDERBY query
I have 2 columns, ID(Primary key), Age(float) in a table T and I need something like the following
SELECT ID FROM T WHERE !> (inputted ID) + 1 rowID/Next row <! ORDERBY Age (then primary key, but I suspect if the Age values are the same SQLite would default to order by primary key anyway) LIMIT 1
Essentially it would select the next row after the inputted ID in the ordered table, its the next row / rowID + 1 I am not sure how to get.
As suggested here is a data set as an example
https://dbfiddle.uk?rdbms=sqlite_3.27&fiddle=19685ac20cc42041a59d318a01a2010f
ID Age
1 12.2
2 36.8
3 22.5
4 41
5 16.7
I am attempting to get the the following row from the ordered (by age) list given a specific ID
ID Age
1 12.2
5 16.7
3 22.5
2 36.8
4 41
Something similar to
SELECT ID FROM OrderedInfo WHERE ID = 5 ORDER BY Age ASC LIMIT 1 OFFSET 1;
My expected result would be '3' from the example data above
I have expanded the data set to include duplicate entries as I didn't implicitly state it could have such data - as such forpas answer works for the first example with no duplicate entries - thanks for your help
https://dbfiddle.uk?rdbms=sqlite_3.27&fiddle=f13d7f5a44ba414784547d9bbdf4997e
Use a subquery for the ID that you want in the WHERE clause:
SELECT *
FROM OrderedInfo
WHERE Age > (SELECT Age FROM OrderedInfo WHERE ID = 5)
ORDER BY Age LIMIT 1;
See the demo.
If there are duplicate values in the column Age use a CTE that returns the row that you want and join it to the table so that you expand the conditions:
WITH cte AS (SELECT ID, Age FROM OrderedInfo WHERE ID = 5)
SELECT o.*
FROM OrderedInfo o INNER JOIN cte c
ON o.Age > c.Age OR (o.Age = c.Age AND o.ID > c.ID)
ORDER BY o.Age, o.ID LIMIT 1;
See the demo.

SQLite Select to compare two last orders in same row

I have created a dataset "Orders" to test sqlite with structure
CREATE TABLE Orders (
OrderID INTEGER PRIMARY KEY AUTOINCREMENT
OrderDate TIMESTAMP DEFAULT (CURRENT_TIMESTAMP)
CustomerID VARCHAR(20)
OrderValue DECIMAL (8, 3) NOT NULL
);
I filled the table with sample data
ID Date Customer Value($)
6 11-09-2019 Eva 6946.3
7 11-10-2019 John 850.6
8 11-11-2019 Helen 9855.0
9 11-12-2019 Maria 765.2
11 11-13-2019 Gui 1879.5 --< I removed ID 10 purposely
12 11-14-2019 Eric 600.0
13 11-15-2019 Paul 12890.1
How could I identify in same row both records 11 and 9, given the parameter :date, to represent the last sale of orderdate = :date and the immediately forward, or in case I changed record 9 to same date of 11, I get 8 (the last sale of last day)?
pseudo-code
select last 2 order where orderdate <= :date inner join (? a relation to put both in same row)
Step one is to replace your 'MM-DD-YYYY' date strings with ones that can be sorted - 'YYYY-MM-DD', for example (Then you can use the date and time functions on them as well if needed). Since your orderdate column has a default value of CURRENT_TIMESTAMP, but you're just showing the date and that not in the same format that uses, I assume you're inserting your dates manually instead of letting them be automatically generated on insert? The column names of your sample data table don't match up with the ones in your table definition either... that's confusing.
Anyways, since you said you want the values in the same row, the lead() window function comes into play (Requires Sqlite 3.25 or newer). Something like:
WITH cte AS
(SELECT orderid, orderdate, customerid, ordervalue
, lead(orderid, 1) OVER bydate AS next_id
, lead(orderdate, 1) OVER bydate AS next_date
, lead(customerid, 1) OVER bydate AS next_customer
, lead(ordervalue, 1) OVER bydate AS next_value
FROM orders
WINDOW bydate AS (ORDER BY orderdate))
SELECT * FROM cte WHERE orderdate = :date;
gives for a :date of '2019-11-12':
orderid orderdate customerid ordervalue next_id next_date next_customer next_value
---------- ---------- ---------- ---------- ---------- ---------- ------------- ----------
9 2019-11-12 Maria 765.2 11 2019-11-13 Gui 1879.5

sql group by with count and add totals row

So my situation. Got a table with few thousand entries, I took one column and counted the number of the same entries.
SELECT mycolumn, COUNT(*)
FROM mytable
WHERE myid = 6867
GROUP BY mycolumn
ORDER BY COUNT(*) DESC
Outputs:
6 885
1 715
4 562
5 557
2 232
3 181
I get the desired results. Now all I need is to add a bottom row with a sum of all counted entries.
Typically you would do this in some reporting tool, like SSRS, not SQL.
To do it in SQL, add a UNION statement:
UNION ALL
SELECT 0, COUNT(*)
FROM mytable
WHERE myid = 6867;

MS Access Query counting instances

I have a sample table with following values
SNO | Mon
-----+-------
100 | 1
101 | 1
102 | 1
100 | 2
101 | 2
102 | 2
100 | 3
101 | 3
Now I need a query to count the total sno's which are in 3 months
The result should be 2, as 100 & 101 are in mon 1,2 and 3. However, 102 is only present in mon 1,2.
Thanks,
RK
This Query in theory should work.
SELECT
tmpTbl.sNo
FROM
tmpTbl
GROUP BY
tmpTbl.sNo
HAVING
Count(tmpTbl.monNo) = (SELECT Count(*) FROM (SELECT tmpTbl.monNo FROM tmpTbl GROUP BY tmpTbl.monNo));
The result would be,
sNo
----
100
101
I have used two SubQueries to get the result. Teh both are used in the HAVING clause of the SQL. First SqubQuery (inner most). Will get the number of Unique Month's available in your table, the outer SubQuery will then Count the number of Unique months. So the Overall Query can be translated as "SELECT the serial number FROM the table HAVING the Count of Month equal to the Number of unique records in the same table".
The reason I used SbQuery instead of a number is because of the fact this will also be applicable when your month number increases. Hope this helps !
EDIT
Here is the Query for getting the count.
SELECT
Count(*) As simpleCount
FROM
(
SELECT
tmpTbl.sNo
FROM
tmpTbl
GROUP BY
tmpTbl.sNo
HAVING
Count(tmpTbl.monNo) = (SELECT Count(*) FROM (SELECT tmpTbl.monNo FROM tmpTbl GROUP BY tmpTbl.monNo))
);

Counting Duplicates from table

I have got a table which i have mentioned below, i need to get a total results avoiding duplicates , can any one provide any assistance or suggestions on how to get the results mentioned below, thankyu
ID name Total Used
24 John 5 2
24 John 10 6
27 Peter 20 0
27 Peter 20 5
Result should be something like this
ID name Total Used
24 John 15 8
27 Peter 40 5
Looks like you just need to use SUM() on the two columns. Also use a GROUP BY on the id and name
SELECT id, name, sum(total) All_total, sum(used) All_used
FROM yourtable
GROUP BY id, name
see SQL Fiddle with Demo
The GROUP BY field must include any other columns you are selecting which are not in an aggregate function, so for the example you would include both id and name in the GROUP BY.
Edit #1 your query would be:
SELECT [ID] , name, sum([Total]), sum([Used]), [GUID]
FROM [table].[dbo].[vw_data]
GROUP BY [ID], [name], [GUID]
select sum(Total), sum(Used), ID, name
from table
group by ID, name;
select ID, name, sum( Total,), sum( Used)
from table
group by Id,name;
Try this:
select id,name, sum(Total),sum(used)
from tab
group by id,name
SELECT id, name, sum(total) total, sum(used) used from table GROUP BY id, name
MySql syntax for this problem:
CREATE TABLE DUPLICATE (ID,NAME, TOTAL, USED);
INSERT INTO DUPLICATE VALUES(24,'John',5,2);
INSERT INTO DUPLICATE VALUES(24,'John',10,6);
INSERT INTO DUPLICATE VALUES(27,'Peter',20,0);
INSERT INTO DUPLICATE VALUES(27,'Peter',20,5);
SELECT ID, NAME, SUM(TOTAL), SUM(USED) FROM DUPLICATE GROUP BY ID, NAME;

Resources