Phonecall Database SQL Queries - sql

I have been working on a database project for a phone call, here is a quick view of the diagram, callid is autoincremented in the call table, and sessionid is auto incremented in the session table, This way on a three way call the calls have the same diagram. I have entered in fictitious data in every field except sessionstarttime and sessionend time
Using phpmyadmin,
My question: I need to do a one query that will give me billable time for the customer aka a phonenumber.
Example phone call
A -> B from 12:00PM to 1:00PM
B -> C from 12:30PM to 1:30PM
A should be billed for 1hour
B should be billed for 1 1/2 hours (1:30 hrs)
C should be billed for 1 hour
Another Example
A -> B 12:00PM to 1:00PM
A -> C 12:30PM to 1:30PM
A should be billed for 1 1/2 hours (1:30 hrs)
B should be billed for 1hour
C should be billed for 1 hour
Here are the given data formats
- <table name="Account">
<column name="AccountID">1</column>
<column name="AcctHolderNum">617-100-5001</column>
<column name="ProviderID">1</column>
</table>
<table name="call">
<column name="callID">4</column>
<column name="callSender">617-719-9000</column>
<column name="callReceiver">617-730-8100</column>
<column name="callStartTime">2012-11-06 06:44:50</column>
<column name="callEndTime">2012-11-06 06:55:50</column>
<column name="sessionID">1</column>
- <table name="phoneNum">
<column name="phoneNum">617-300-2000</column>
<column name="phoneNumFN">Nigel</column>
<column name="phoneNumLN">Thornberry</column>
<column name="PhoneAccountID">2</column>
- <table name="Provider">
<column name="ProviderID">1</column>
<column name="ProviderName">T-Mobile</column>
</table>
- <table name="session">
<column name="sessionID">1</column>
<column name="sessionStartTime">2012-11-06 06:44:50</column>
<column name="sessionEndTime">2012-11-06 06:55:50</column>
Here is the ER diagram
http://i.stack.imgur.com/rrh4B.jpg
Here is what I got started thinking but drown myself in confusion trying to make the one query fit every possible input in the call table
FROM `call` as `call1`, `call` as `call2`, `call` as `call3`
WHERE `call1.sessionid` = `call2.sessionid` = `call3.sessionid`
AND <REST OF STUFF>
UNION /* not union all, but union*/
SELECT same as above but for three way calls
FROM `call` as `call1`, `call` as `call2`,
WHERE `call1.sessionid` = `call2.sessionid`
AND <REST OF STUFF>
UNION
SELECT same as above but for two way calls
FROM `call`
WHERE <REST OF STUFF>
Also here are a couple of simple queries for reference
Calculates length of each call
SELECT TIMEDIFF(MIN(`callStartTime`), MAX(`callEndTime`))
FROM `call` GROUP BY `callID`
Calculates length of each session
SELECT TIMEDIFF(MIN(`callStartTime`), MAX(`callEndTime`))
FROM `call` GROUP BY `sessionID`
Minutes of calls made (note callsender) by account
SELECT SUM(TIMEDIFF(`callStartTime`, `callEndTime`))
FROM `call`, `Phonenum`
WHERE `phoneNum.phoneNum` = `call.callSender`
GROUP BY `phoneAccountID`
Minutes of calls recieved (note callreciever) by account
SELECT SUM(TIMEDIFF(`callStartTime`, `callEndTime`))
FROM `call`, `Phonenum`
WHERE `phoneNum.phoneNum` = `call.callReciever` GROUP BY `phoneAccountID`
Here is the xml output for the schema
- <pma:structure_schemas>
- <pma:database name="jr_Team5" collation="utf8_general_ci" charset="utf8">
<pma:table name="Account">CREATE TABLE `Account` ( `AccountID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'AI Primary Key', `AcctHolderNum` varchar(50) NOT NULL COMMENT 'Account Holder''s Phone Number i.e. "617-100-5001"', `ProviderID` int(11) DEFAULT NULL COMMENT 'Foreign Key from "ProviderID"', PRIMARY KEY (`AccountID`), KEY `AcctHolderNum` (`AcctHolderNum`), KEY `ProviderID` (`ProviderID`), CONSTRAINT `Account_ibfk_1` FOREIGN KEY (`ProviderID`) REFERENCES `Provider` (`ProviderID`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;</pma:table>
<pma:table name="call">CREATE TABLE `call` ( `callID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'AI Primary Key', `callSender` varchar(50) NOT NULL COMMENT 'Phone Number of Caller', `callReceiver` varchar(50) NOT NULL COMMENT 'Phone Number of Reciever', `callStartTime` datetime NOT NULL COMMENT 'Time Call Begins', `callEndTime` datetime NOT NULL COMMENT 'Time Call Ends', `sessionID` int(11) NOT NULL COMMENT 'Foreign Key from "SessionID"', PRIMARY KEY (`callID`), KEY `callSender` (`callSender`), KEY `callReceiver` (`callReceiver`), KEY `sessionID` (`sessionID`), CONSTRAINT `call_ibfk_1` FOREIGN KEY (`callSender`) REFERENCES `phoneNum` (`phoneNum`), CONSTRAINT `call_ibfk_2` FOREIGN KEY (`callReceiver`) REFERENCES `phoneNum` (`phoneNum`), CONSTRAINT `call_ibfk_3` FOREIGN KEY (`sessionID`) REFERENCES `session` (`sessionID`) ) ENGINE=InnoDB AUTO_INCREMENT=61 DEFAULT CHARSET=utf8;</pma:table>
<pma:table name="phoneNum">CREATE TABLE `phoneNum` ( `phoneNum` varchar(50) NOT NULL COMMENT 'Phone Number on Record', `phoneNumFN` varchar(50) DEFAULT NULL COMMENT 'First Name of Phone User', `phoneNumLN` varchar(100) DEFAULT NULL COMMENT 'Last Name of Phone User', `PhoneAccountID` int(11) DEFAULT NULL COMMENT 'Foreign Key from "AccountID"', PRIMARY KEY (`phoneNum`), KEY `PhoneAccountID` (`PhoneAccountID`), CONSTRAINT `phoneNum_ibfk_1` FOREIGN KEY (`PhoneAccountID`) REFERENCES `Account` (`AccountID`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;</pma:table>
<pma:table name="Provider">CREATE TABLE `Provider` ( `ProviderID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'AI Primary Key', `ProviderName` varchar(50) NOT NULL COMMENT 'Network Provider i.e. "Verizon" or "Sprint"', PRIMARY KEY (`ProviderID`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;</pma:table>
<pma:table name="session">CREATE TABLE `session` ( `sessionID` int(11) NOT NULL AUTO_INCREMENT COMMENT 'AI Primary Key', `sessionStartTime` datetime DEFAULT NULL COMMENT 'Session Begin Time', `sessionEndTime` datetime DEFAULT NULL COMMENT 'Session End Time', PRIMARY KEY (`sessionID`) ) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8;</pma:table>
</pma:database>
</pma:structure_schemas>
Thanks for your help in advance,any help/input/direction would be appreciated let me know if you think of any other complex queries possible for this database
Fourway call data example in xml
- <table name="call">
<column name="callID">40</column>
<column name="callSender">617-292-1309</column>
<column name="callReceiver">617-300-2000</column>
<column name="callStartTime">2012-10-31 09:07:35</column>
<column name="callEndTime">2012-10-31 11:07:35</column>
<column name="sessionID">7</column>
</table>
- <table name="call">
<column name="callID">41</column>
<column name="callSender">617-300-2000</column>
<column name="callReceiver">617-234-1234</column>
<column name="callStartTime">2012-10-31 09:37:35</column>
<column name="callEndTime">2012-10-31 12:37:35</column>
<column name="sessionID">7</column>
</table>
- <table name="call">
<column name="callID">42</column>
<column name="callSender">617-234-1234</column>
<column name="callReceiver">617-200-4000</column>
<column name="callStartTime">2012-10-31 10:37:35</column>
<column name="callEndTime">2012-10-31 11:37:35</column>
<column name="sessionID">7</column>

I think you have two problems here. The first is determining how much time to allot to each caller in a session. The second is to aggregate this information.
Let me assume that all the time for a given phone number in a session is contiguous. That is, there is no call from B--> from 12:00 to 12:15 (because C would not be contiguous). Then you can get the timings for each user within a session:
select c.sessionid, c.caller,
(max(c.EndTime) - min(c.StartTime)) as dur
from ((select c.sessionid, c.callSender as caller, c.StartTime, c.EndTime
from call c
) union all
(select c.sessionid, c.callReceiver, c.StartTime, c.EndTime
from call c
)
) c
on s.sessionid = c.sessionid
group by c.sessionid, c.caller
From this, you can then aggregate over all sessions.
If the calls periods within a session are not contiguous, then the problem is more challenging. The best way to solve this problem depends on the database and the functions available in the database.

Related

Add auto increment column to an existing table ordered by created time

I have below table in Oracle db (ATP db)
create table record(
record_id raw(16) primary key,
dataset_id raw(16) not null,
name varchar2(127) not null,
time_created timestamp not null,
CONSTRAINT record_fk_dataset_id foreign key (dataset_id) references dataset(dataset_id),)
partition by reference (record_fk_dataset_id);
I would like to add new auto-increment column id in sequence with time_created, eg. records are created in this order of time_created 1st record at 02/12/2021 12:37:37 PM 2nd record at 02/12/2021 12:40:45 PM
1st record to get id as 1 and 2nd id as 2.
I have some data in record table already.
Edit:
time_created can have duplicate entries too.

ORA-00918: column ambiguously defined [duplicate]

This question already has an answer here:
ORA 00918- Column ambiguosly defined error [duplicate]
(1 answer)
Closed 9 years ago.
I am trying to retrieve some data (coursename) from one of my tables but the following error is coming all the time
ORA-00918: column ambiguously defined
the command I am typing is:
select bookno,courno,coursename
from booking, course,coursename
where bookno = 6200
and booking.courno = course.courno
and coursename.coursenameno = course.coursenameno
I have some tables as described :
CREATE TABLE BOOKING
(BOOKNO NUMBER (4) NOT NULL,
COURNO NUMBER (4) NOT NULL,
BOOKDATE DATE,
BOOKCUSTPAYMENT VARCHAR (20),
CONSTRAINT PK_BOOK PRIMARY KEY (BOOKNO,COURNO),
CONSTRAINT FK_BOOK FOREIGN KEY (COURNO) REFERENCES COURSE(COURNO)
ON DELETE CASCADE);
CREATE TABLE CUSTOMER
(CUSTNO NUMBER (4) NOT NULL, -- creation of primary-key
PROFNO NUMBER (4) NOT NULL,
CUSTFNAME VARCHAR (15),
CUSTLNAME VARCHAR (15),
CUSTDOB DATE,
CUSTPHONEDAY NUMBER (15),
CUSTPHONEEVE NUMBER (15),
CONSTRAINT PK_CUST PRIMARY KEY (CUSTNO),
CONSTRAINT FK_PROF FOREIGN KEY (PROFNO) REFERENCES PROFICIENCY(PROFNO)
ON DELETE CASCADE);
CREATE TABLE COURSENAME
( COURSENAMENO NUMBER (4) NOT NULL,
COURSENAME VARCHAR (20),
COURSEDESC VARCHAR (120),
COURSEDAYCOST NUMBER (7,2),
CONSTRAINT PK_COURSENAME PRIMARY KEY (COURSENAMENO));
CREATE TABLE COURSE
(COURNO NUMBER (4) NOT NULL, -- creation of primary-key
COURSTART DATE,
COUREND DATE,
COURSENAMENO NUMBER (4) NOT NULL,
ACCDAYNO NUMBER (4) NOT NULL,
FOODNO NUMBER (4) NOT NULL,
TRANSNO NUMBER (4) NOT NULL,
CONSTRAINT PK_COURSE PRIMARY KEY (COURNO),
CONSTRAINT FK_COURSENAME FOREIGN KEY (COURSENAMENO) REFERENCES COURSENAME(COURSENAMENO));
I am researching but I cannot figure out what is happening !!!
when the same column appears in several tables you need to specify which table is the one to be used. As a general rulem its always a good idea to prefix the column with the table (or alias) as improves readability and speeds up parsing.
so, for your query try (changes in upper case)
select BOOKING.bookno,BOOKING.courno,COURSENAME.coursename
from booking, course,coursename
where BOOKING.bookno = 6200
and booking.courno = course.courno
and coursename.coursenameno = course.coursenameno
You need to specify from which table the columns in SELECT and WHERE statements should be retrieved:
select booking.bookno, booking.courno, course.coursename
from booking, course, coursename
where booking.bookno = 6200
and booking.courno = course.courno
and coursename.coursenameno = course.coursenameno
Also, consider using ANSI SQL-92+ JOIN syntax like so:
select booking.bookno, booking.courno, course.coursename
from booking
inner join course on booking.courno = course.courno
inner join coursename on coursename.coursenameno = course.coursenameno
where booking.bookno = 6200
See [Bad habits to kick : using old-style JOINs][1] for some reasoning about it.
[1]: https://sqlblog.org/2009/10/08/bad-habits-to-kick-using-old-style-joins
When a column is ambigious, this means the database doesnt know which column to use from 2 or more different tables.
You must define in the select like this
select tablename.bookno,tablename.courno,tablename.coursename
from booking, course,coursename
where tablename.bookno = 6200
and booking.courno = course.courno <-- Here its correct
and coursename.coursenameno = course.coursenameno <-- Here its correct
Change tablename. to the correct table where the column is.
field courno in your select: you haven't defined from which table: course or booking

Microsoft Access - Enter Parameter Value why?

I am encountering a problem for my database.
And tried to do the query for how many transactions have movie "Harry_Potter"?
so I used SQL query:
SELECT
COUNT(td.movie) AS number_of_occurrence,
td.transaction_number
FROM
TransactionDetails td,
MovieDetails md
WHERE
md.movie = Harry_Potter
But it asks for Harry_Potter enter parameter value why?
The relevant SQL statements are
CREATE TABLE TransactionDetails
(
transaction_number INTEGER PRIMARY KEY,
movie VARCHAR(30) NOT NULL,
date_of_transaction DATE NOT NULL,
member_number INTEGER NOT NULL
)
CREATE TABLE MovieDetails
(
movie VARCHAR(30) PRIMARY KEY,
movie_type VARCHAR(3) NOT NULL,
movie_genre VARCHAR(10) NOT NULL
)
ALTER TABLE TransactionDetails
ADD CONSTRAINT member_number_fk FOREIGN KEY (member_number) REFERENCES LimelightMemberDetails(member_number);
ALTER TABLE TransactionDetails
ADD CONSTRAINT transaction_number_drink_fk FOREIGN KEY (transaction_number) REFERENCES DrinkTransactionDetails(transaction_number);
ALTER TABLE TransactionDetails
ADD CONSTRAINT transaction_number_food_fk FOREIGN KEY (transaction_number) REFERENCES FoodTransactionDetails(transaction_number);
ALTER TABLE TransactionDetails
ADD CONSTRAINT movie_fk FOREIGN KEY (movie) REFERENCES MovieDetails (movie);
Thank you for your help! If there is anything wrong with my database design please let me know! thank you!
Change the query to something like
SELECT
COUNT(td.movie) AS number_of_occurrence,
td.transaction_number
FROM
TransactionDetails td,
MovieDetails md
WHERE
md.movie = "Harry_Potter"
Seeing as movie is a string, you need quotes around the value you are looking for.
If I am not mistaken MS Access takes " and SQL SERVER takes '
try this
md.movie = "Harry_Potter"
I guess, you are simply missing the quotation marks around the string you are comparing.

PK Violation on a history table

This is in SQL Server 2005.
I have an address table:
dbo.Address
(
AddressID INT IDENTITY(1, 1) PRIMARY KEY
LastUpdateBy VARCHAR(30)
<bunch of address columns>
)
I also have a history table:
dbo.AddressHistory
(
AddressID INT,
AsOf DATETIME,
UpdateBy VARCHAR(30)
<all the address columns>
CONSTRAINT PK_dbo_AddressHistory PRIMARY KEY CLUSTERED (AddressID, AsOf)
)
I have a trigger on dbo.Address to create history entries on both INSERT and UPDATE which will basically do this:
INSERT INTO dbo.AddressHistory(AddressID, AsOf, UpdateBy, <address columns>)
SELECT AddressID, CURRENT_TIMESTAMP, #UpdateBy, <address columns>
FROM INSERTED
But, every once in while, I'll get a PK violation on dbo.AddressHistory complaining about a duplicate PK being inserted. How is this possible if part of the PK for AddressHistory is the current timestamp of the insertion?
Even executing this will insert two rows into the history table successfully:
INSERT INTO dbo.Address
(LastUpdateBy, <address columns>)
SELECT 'test', <address columns>
FROM dbo.Address
WHERE AddressID < 3
And the only update sproc I have for the dbo.Address table will update a row for a given AddressID. So it should only be updating one row at a time. My insert sproc only inserts one row at a time as well.
Any idea what conditions cause this to occur?
Based on your description two concurrent executions of the stored procedure with the same parameter would seem likely.
datetime only has a precision of 1/300 second so conflicts can occur if these executions happen very close together.

MySQL unique clustered constraint not constraining as expected

I'm creating a table with:
CREATE TABLE movies
(
id INT AUTO_INCREMENT PRIMARY KEY,
name CHAR(255) NOT NULL,
year INT NOT NULL,
inyear CHAR(10),
CONSTRAINT UNIQUE CLUSTERED (name, year, inyear)
);
(this is jdbc SQL)
Which creates a MySQL table with a clustered index, "index kind" is "unique", and spans the three clustered columns:
mysql screen http://img510.imageshack.us/img510/930/mysqlscreenshot.th.jpg
full size
However, once I dump my data (without exceptions thrown), I see that the uniqueness constraint has failed:
SELECT * FROM movies
WHERE name = 'Flawless' AND year = 2007 AND inyear IS NULL;
gives:
id, name, year, inyear
162169, 'Flawless', 2007, NULL
162170, 'Flawless', 2007, NULL
Does anyone know what I'm doing wrong here?
MySQL does not consider NULL values as equal; hence, why the unique constraint appears to not be working. To get around this, you can add a computed column to the table which is defined as:
nullCatch as (case when inyear is null then '-1' else inyear)
Substitute this column in for 'inyear' in the constraint:
CONSTRAINT UNIQUE CLUSTERED (name, year, nullCatch)