How to write an SQLite query that uses 4 tables and count()? - sqlite

I've got 4 tables that I want data from.
Trip_T
tripID (PK)
userID (FK)
...
User_T
userID (PK)
username
...
Excursion_T
excursionID (PK)
tripID (FK)
...
POI_T
poiID (PK)
excursionID (FK)
...
I want to create a table with one row for each trip in the db.
Each row should include the tripID, title, the user's name associated with the trip, the number of excursions made on the the trip and the number of poi (points of interest) associated with those excursions.
I'm using the following query:
SELECT Trip_T.tripID, Trip_T.title, User_T.username
COUNT(DISTINCT Excursion_T.excursionID) AS numExcursions,
COUNT(DISTINCT POI_T.poiID) AS numPOI
FROM Trip_T
INNER JOIN User_T ON User_T.userID = Trip_T.userID
INNER JOIN Excursion_T ON Excursion_T.tripID = Trip_T.tripID
INNER JOIN POI_T ON POI_T.excursionID = Excursion_T.excursionID
Even though I have multiple trips in the db, each with multiple excursions and pois, the query returns 1 row with what looks like the total number of excursions and total number of pois for all trips.
Any help is appreciated.

You forgot to add grouping to your query:
GROUP BY Trip_T.tripID, Trip_T.title, User_T.username
This way the counters correspond to each triplet of (Trip_T.tripID, Trip_T.title, User_T.username)

Related

INNER JOIN to get Max value from one table and return the name from another table. (SQlite)

I have created 2 tables:
CREATE TABLE locations(location STRING, id INT);
CREATE TABLE temperatures(location_id INT, temperature INT, day INT)
I am using SELECT location_id, day, MAX(temperature) FROM temperatures; to get the max Temperature out of every day from a single location(the location is mentioned in the URL by id). Is there a way that I can get the location from locations table based on the id? So the result will be something like :
61.1435,-1.1234 | 5 |35.5
instead of :
0 | 5 | 35.5
In simple words I want to replace the location_id of the result with the actual location (coordinates).
Why do you not join the two tables? Something like:
SELECT locations.location, temperatures.day, temperatures.temperatur FROM temepratures, locations where temperatures.location_id = locations.id
Or search in google for JOINS, you will find your answer.

Optimize JOIN for a large dataset in SQLite

I need to create a table with the running total (aka cumulative sum) per client per day from a large dataset (200 GB). However, my current code is too slow: it has been running for days and still has not finished.
My data came from two tables. The table Orders informs the order id and client id. The table Transactions informs the order id, date and status (status=5 means order approved, status=7 means order rejected).
CREATE TABLE RunningTotal AS
SELECT DISTINCT Orders.ClientId,
Transactions.Date,
SUM(CASE WHEN Transactions.Status = 5 THEN 1 ELSE -1 END) OVER (PARTITION BY Orders.ClientId ORDER BY Transactions.Date) AS RunTotal
FROM Transactions
LEFT JOIN Orders ON Transactions.Order_Id= Orders.Id
WHERE Transactions.Status IN (5,7)
I used a toy table to test and my current code provides the expected results: the net running total of approved order per client per day. The problem seems to be how to optimize it to use with a large dataset. I might be wrong, but I believe my bottleneck is the JOIN. If I run a similar query with just one table, it takes minutes.
The command EXPLAIN QUERY PLAN gives​ me the following:
CO-ROUTINE 3
SEARCH TABLE Transactions USING INDEX idx_trans_status (Status=?)
SEARCH TABLE Orders USING INDEX idx_orders_id (Id=?)
USE TEMP B-TREE FOR ORDER BY
SCAN SUBQUERY 3
USE TEMP B-TREE FOR DISTINCT
USE TEMP B-TREE FOR ORDER BY
EDIT:
The output table would look like:
CREATE TABLE Transactions (
ClientId INTEGER,
Date DATE,
RunTotal INTEGER
PRIMARY KEY (ClientId, Date)
)
ClientId Date RunTotal
-------- ----------- --------
1 2018-12-28 110
1 2018-12-30 125
3 2018-10-15 87
3 2018-11-22 93
3 2018-11-24 99
'Orders' table looks like:
CREATE TABLE Orders (
Id INTEGER,
ClientId INTEGER
Class INTEGER,
Recall INTEGER,
Family INTEGER,
CreationDate DATE,
DeletionDate DATE,
Level INTEGER,
Notes TEXT,
Tags TEXT,
Operator_ID INTEGER,
Node INTEGER,
PRIMARY KEY (Id)
)
'Transactions' table looks like:
CREATE TABLE Transactions (
Id INTEGER,
Order_Id INTEGER,
Date DATE,
Status INTEGER,
Amount INTEGER,
Operator_ID INTEGER,
Notes TEXT,
PRIMARY KEY (Id)
)

Trying to get one Column from random query in sqlite

Hello I have the following query in SQLite. ISBN is a text variable.
insert into BOOK_ORDER
SELECT OrderID FROM tableOrder WHERE OrderID = 1 UNION SELECT ISBN FROM BOOK ORDER BY random() LIMIT 1;
I am trying to add two columns together
However I get an error:
1st ORDER BY term does not match any column in the result set:
insert into BOOK_ORDER
SELECT OrderID FROM tableOrder WHERE OrderID = 1 UNION SELECT ISBN FROM BOOK
ORDER BY random() LIMIT 1;
I want to have a two column result table:
OrderID ISBN
4 192374125
EDIT:
I think I need to use a cross join, can someone help me?
UNION results in more rows (unless they are duplicates).
To get more columns, you have to list all of them in the SELECT clause.
In this case, you can use subqueries:
insert into BOOK_ORDER
VALUES ((SELECT OrderID FROM tableOrder WHERE OrderID = 1),
(SELECT ISBN FROM BOOK ORDER BY random() LIMIT 1));

Get unique row or merge the values on unique rows

SQLServer2008R2 and ASP.NET(VB) - VS2012
I am tring to use many-to-many relationship. I have a table to enter users, another one for the incidents and created a join table with the primary key from both the tables. I am trying to display top 20 incidents from the incident table and get the patron id from join table and then get the name of the patron from patron table. For an incident with two patrons, it creates two rows. I tried to use GROUP by but the query did not like it. Is there a way that I can display only one incident id with both patron names listed?
SELECT TOP (20)
tblIncident.Inci_ID
,tblIncident.Library
,tblIncident.Inci_date
,tblIncident.Inci_time
,tblIncident.Created_By
,tblJoin.PatronID AS Patron_ID
,tblPatron.FName + ' ' + tblPatron.LName AS FullName
FROM tblIncident
INNER JOIN tblJoin ON tblIncident.Inci_ID = tblJoin.InciID
INNER JOIN tblPatron ON tblJoin.PatronID = tblPatron.PatronID
WHERE tblIncident.Active = 'True'
ORDER BY tblIncident.Inci_date DESC

find count of distinct values in a column

Hi all am trying to build a sql query to display some information on a dashboard.
I have a table in which i store my sales data.My query needs to find total sales in last 7 days,average and group it based on region(which is present in user table.) .I created a temp table to get the item sales.DashBoard_Items table contains particular item that needs to be shown on dashboard.Now my problem is i need to get the store count of each region to find average sales.Can some one please help
Declare #TableTest
table(itemid int,itemname varchar(100),itemdescription varchar(100),id int,itemidd int,userid int,orderdate varchar(40),qty int)
insert into #TableTest
select * from DashBoard_Items join
SalesQTY on SalesQTY.OrderDate>= CONVERT(varchar(10) , DATEADD(DAY,-7,GETDATE()),126)
and OOS_DashBoard_CoreItems.itemid=SalesQTY.itemid
select distinct t.userid,u.region from #TableTest t join users u on t.userid=u.userid and region is not null
above select query returns
how can i get region count from the above select query
region count
5 - SUN WEST 2
2 - LONG ISLAND 3
You need to group by region and then use cont(*)
SELECT region, count(*)
FROM #TableTest
GROUP BY region;
Please try:
SELECT
Region,
COUNT(*) AS [Count]
FROM YourTable
GROUP BY Region
OR
SELECT
DISTINCT Region,
COUNT(*) OVER (PARTITION BY Region) AS [Count]
FROM YourTable
SELECT u.region, COUNT(*)
FROM #TableTest t JOIN users u ON t.userid=u.userid AND u.region IS NOT NULL
GROUP BY u.region
try
SELECT region, count( * )
FROM mytable
GROUP BY region

Resources