Query to get current remaining stock in sqlite - sqlite

I have a table named stock:
name stock
------------
a 100
b 200
c 50
and a sales table
name sale
--------------------
a 30
c 20
d 30
The result should be:
name stock
-----------------
a 70
b 200
c 20
d -30
Please tell me the sqlite query for this.
My query:
select a.name, a.stock - b.sales as stock
from stock as a
inner join Sale as b on a.name = b.name
but how to get those name which doesn't exists in stock but exists in sales?

I believe the following will do what you want :-
SELECT name, sum(stock) - sum(sold) FROM
(
SELECT name, sold, 0 as stock FROM sales
UNION ALL
SELECT name, 0 AS sold, stock FROM stock
)
GROUP BY name
ORDER BY name
Basically the inner SELECT extracts a table with 3 columns name, sold and stock for each combination and with 0 as the missing value. i.e. :-
This is then used as the source of the outer SELECT which groups according to name summing the sales and the stock and subtracting the sales from the stock as per :-

Related

SQL Query: Select the sum(quantity) and count(number) SQLite

I am trying to query the chinnok database to select sum of quantity tracks purchase and count the number of times the track appears in a playlist in one query.
Here is what I have:
/* Query 3 : which artist has the most songs on the top 100 songs across playlist and the most sold
songs*/
SELECT ar.Name Artist_Name, tr.Name Track_Name, count(pl.Name) Play_List, pt.TrackId Track_ID,
SUM(il.Quantity) Qty,
CASE WHEN count(pl.Name)=5 THEN "Five Stars"
ELSE "Four Star" END AS Ranking
FROM Track tr
JOIN PlaylistTrack pt
ON pt.TrackId = tr.TrackId
JOIN Playlist pl
ON pl.PlaylistId=pt.PlaylistId
JOIN Album ab
ON ab.AlbumId = tr.AlbumId
JOIN Artist ar
ON ar.ArtistId = ab.ArtistId
JOIN InvoiceLine il
ON il.TrackId = tr.TrackId
GROUP BY tr.TrackId
ORDER BY Play_List DESC
LIMIT 100;
Here is the results:
Fist 6 results
First 16 results
The Qty is correct but the Play_list number is not.
Can anyone help?

Why does COUNT return NULL instead of `0` in this query?

I have the query
select d.did, count ( h.did ), unique_interested
from dealer as d
left outer join house as h
on h.did = d.did
left outer join (
-- cid = customer id
select hid, count (cid) as unique_interested
from is_interested
group by hid
) as ok
on h.hid = ok.hid
group by d.did
order by d.did asc
;
which is supposed to select the number of houses that each dealer is dealing, and the number of unique customers interested in said houses (as in the number of customers per dealer). This should happen even if the dealers have no houses to deal at the moment, which is why I'm using left outer joins when constructing the table the columns will be picked from.
Now, running this query against my database produces the following output:
d.did count ( h.did) unique_interested
----- -------------- ----------------
1 3
2 3 1
3 0
As you can see, instead of printing 0 in the last column, count returns null, when there is a null in one of the aparments produced by the last part of the join (as in cid is null):
select hid, count ( cid ) as unique_interested
from is_interested
group by hid
I know this is because there are apartments in the table produced by from, that no-one is interested in. But shouldn't count produce 0 instead of the actual column value null in every case?
Any explanation as to why this is happening would be appreciated, as it would lead me towards an answer to another question, which is "Why am I not getting the right number of unique interested customers per dealer from the table is_interested?", as with the current state of my database, the output should look more like:
d.did count ( h.did) unique_interested
----- -------------- ----------------
1 3 2
2 3 2
3 0 0

Teradata - OLAP Functions - filter rows

I'm wondering if I can use an OLAP Function to filter irrelevant rows like this:
If I have one matching value (the fourth fields) all the rows with the same key ( the first 3 fields) must not be displayed
In this example, the matching value would be 'C':
Entities product ID Solde
997 0050 123 D
997 0050 123 D
997 0050 123 C
899 0124 125 D
899 0124 125 D
So here My key is composed by entities/product/ID, regarding the value of "Solde" I need to display or not.
Here the the undesired value is Solde = C.
In this example only the last row should be diplayed, because the key 899/0124/125 has only rows with solde = 'D'
The key 997/0050/123 has one row with solde = 'C' so I don't want to display it
Thanks in advance for your helping
Christophe
Updated answer
The more traditional way to solve this is to first select the Entities/Product/ID records that you DON'T want.
SELECT Entities, Product, ID FROM table WHERE Solde<>'D';
Use that result in a subquery in your WHERE clause to exclude those:
SELECT DISTINCT Entities, Product, ID, Solde
FROM table
WHERE (Entities, Product, ID) NOT IN ( SELECT Entities, Product, ID FROM table WHERE Solde<>'D');
Alternatively using a HAVING clause and aggregating
SELECT Entities, Product, ID
FROM table
COUNT(*) = SUM(CASE WHEN Solde = 'D' THEN 1 ELSE 0 END)
GROUP BY 1,2,3
I guess you are looking for answer as the below:
SELECT Solde
FROM yourtable
QUALIFY COUNT(*) OVER (PARTITION BY Entities, Product, ID, Solde) = 1;

in SQLite, how to do a Join avoiding specific duplicates in a column

I’m trying to extract, from a SQLite database, a set of records using a join, avoiding duplicates in one column. The problem is as follows: I have two tables, Table_A has multiple “Names” for the same row in Table_B, but I only need the first name (order by Table_A.Id). So, in the example below, I only want Alfa and Gamma in my results.
Here is an example:
Table _A
Id bId Name
----- ------ ----
1 1 Alfa
2 1 Beta
3 2 Gamma
4 2 Delta
Table_B
Id Year Title
----- ------ ------
1 1900 Doctor
2 1920 Priest
The result that I’m looking for is,
bId Name Year Title
------ ------ ----- ------
1 Alfa 1900 Doctor
2 Gamma 1920 Priest
The obvious join is as follows:
Select bID, Name, Year, Title from Table_A as a join Table_B as b on b.id=a.bid
order by bId;
Which return the following data, including beta and delta, which I don’t need.
bId Name Year Title
----- ------ ------ ------
1 Alfa 1900 Doctor
1 Beta 1900 Doctor
2 Gamma 1920 Priest
2 Delta 1920 Priest
If I change the query to
Select bID, Name, Year, Title from Table_A as a join Table_B as b on b.id=a.bid
group by bId order by bId;
Then I get something like this result that is also wrong (I get Beta & Delta instead of Alfa & Gamma)
bId Name Year Title
----- ------ ------ ------
1 Beta 1900 Doctor
2 Delta 1920 Priest
Which is not good either.
I have tried to find how to do this in SQLite, by looking at the syntax and using Google, and had been unable to find an answer. Will appreciate any help.
SELECT bID, Name, Year, Title
FROM Table_A AS A INNER JOIN Table_B AS B on B.id = A.bid
WHERE NOT EXISTS (SELECT * FROM Table_A WHERE bid = A.bid AND id < A.id)
ORDER BY bId;
This filters the results keeping only the records for which a lower id value cannot be found for the same bid value. Not highly-performant but in the case of not-huge tables it may be sufficiently quick for your needs.
Alternatively:
SELECT bID, Name, Year, Title
FROM Table_A AS A INNER JOIN Table_B AS B on B.id = A.bid
WHERE id = (SELECT MIN(id) FROM Table_A WHERE bid = A.bid)
ORDER BY bId;
If you have SQLite 3.7.11 or later, you can select which record in a group is returned by using MIN or MAX.
In this query, add MIN(A.Id) to the SELECT clause.

select rows from a table with date in the region- 90days ago and now.?

SELECT gameratingstblx245v.gameid,avg( gameratingstblx245v.rating ) as avgrating, count(gameratingstblx245v.rating) as count,gamedata.name ,gamedata.gameinfo
FROM gameratingstblx245v
LEFT JOIN gamedata ON gamedata.id = gameratingstblx245v.game_id
WHERE gameratingstblx245v.game_id=gameratingstblx245v.game_id
GROUP BY gameid
ORDER BY avg( gameratingstblx245v.rating ) DESC LIMIT 0,8
Table gameratingstblx245v - gameid, rating
Rable gamedata - id, gameinfo, name, releasedate
This is the query I am currently using to extract data from two tables gamedata and gameratingstblx245v.... What I am doing here is taking the avg. of all the ratings from table gameratingstblx245v in descending order of their avg. rating and I am also extracting the related info corresponding to the selected gameid's from table gamedata...
Now what I want to extract is the top avg. ratings from game_ratingstblx245v but for the games whose field releasedate from table gamedata is in the last 90 days...
Help would be appreciated..Thanks
Here's how I'd design that query:
SELECT d.id, d.name, d.gameinfo,
AVG(r.rating) AS avgrating, COUNT(r.rating) AS count
FROM gamedata d
LEFT JOIN gameratingstblx245v r ON (d.id = r.game_id)
WHERE d.releasedate BETWEEN NOW() - INTERVAL 90 DAY AND NOW()
GROUP BY d.id
ORDER BY avgrating DESC LIMIT 0,8;

Resources