Android : SQLITE Select Query - java

I have one table of student_fee where columns are :
id_fee
id_student
student_name
fee_month
Here i am inserting data based on students with their monthly tuition fee payment.
From this easily i can query which students paid their monthly fees, suppose January fee by Query Like : Select * From student_fee Where fee_month = "January";
But how can i search which students not paid their monthly fee only in January?

normaly you should have normalized database tables to avoid storing the student name over and over and over again:
<!-- sql -->
CREATE TABLE students ( id INTEGER, name varchar(60));
INSERT INTO students ( id , name ) VALUES (1, 'stud_1');
INSERT INTO students ( id , name ) VALUES (2, 'stud_2');
INSERT INTO students ( id , name ) VALUES (3, 'stud_3');
INSERT INTO students ( id , name ) VALUES (4, 'stud_4');
INSERT INTO students ( id , name ) VALUES (5, 'stud_5');
CREATE TABLE student_fee (id INTEGER, studentId INTEGER, month varchar(20));
INSERT INTO student_fee (id , studentId , month ) VALUES (1, 1, 'january');
INSERT INTO student_fee (id , studentId , month ) VALUES (2, 2, 'january');
INSERT INTO student_fee (id , studentId , month ) VALUES (4, 2, 'february');
INSERT INTO student_fee (id , studentId , month ) VALUES (5, 3, 'february');
INSERT INTO student_fee (id , studentId , month ) VALUES (6, 4, 'february');
And you would query it like so:
select *
from students
where not exists (
select 1
from student_fee
where students.id = studentid
and month = 'january')
Output:
id name
3 stud_3
4 stud_4
5 stud_5
(Sql Syntax is mysql, not sure about sqlite)

Related

Oracle Identity column with custom grouping column

I am working on a requirement where I need to populate a unique constant identifier on a row which is the manager row and unique in each department. My table structure is
CREATE
TABLE TEST_ORGANIZATION
(
EMPLOYEE_ID NUMBER NOT NULL,
MANAGER_ID NUMBER,
FIRST_NAME VARCHAR2(256),
DEPARTMENT_ID VARCHAR2(28) NOT NULL,
UUID VARCHAR2(28) ,
PRIMARY KEY(UUID)
);
This table contains information as.
UUID
DEPARTMENT_ID
EMPLOYEE_ID
MANAGER_ID
FIRST_NAME
radmon1
finance
employee1
John B
radmon2
finance
employee2
employee1
Michal
radmon3
finance
employee3
employee1
Ronaldo
radmon4
finance
employee4
employee1
Thomas
radmon5
finance
employee5
Percey
radmon6
account
employee6
Stacy
radmon7
account
employee7
Jordan
radmon8
account
employee8
employee6
Micky
radmon9
account
employee9
employee6
Author
radmon10
account
employee10
employee6
Gordan
I would like to add another column to the table to provide a sequence to managers only (where Manager_ID is null). But, the sequence should be grouped with DEPARTMENT_ID
ALTER TABLE TEST_ORGANIZATION ADD SEQUENCE_ID NUMBER
UUID
DEPARTMENT_ID
EMPLOYEE_ID
MANAGER_ID
FIRST_NAME
SEQUENCE_ID
radmon1
finance
employee1
John B
1
radmon2
finance
employee2
employee1
Michal
radmon3
finance
employee3
employee1
Ronaldo
radmon4
finance
employee4
employee1
Thomas
radmon5
finance
employee5
Percey
2
radmon6
account
employee6
Stacy
1
radmon7
account
employee7
Jordan
2
radmon8
account
employee8
employee6
Micky
radmon9
account
employee9
employee6
Author
radmon10
account
employee10
employee6
Gordan
I tried using sequence and identity columns added after oracle 12/19c.
I could it programmatically from backend service and update SEQUENCE_ID using
Select NVL(MAX(SEQUENCE_ID), 0) + 1 FROM TEST_ORGANIZATION WHERE MANAGER_ID is NULL AND DEPARTMENT_ID = ? query. But, I would like to know if there is any function in Oracle 19c to handle this behaviour on the Database side itself.
Try This:
SELECT d1.*,
1 AS f,
CASE WHEN manager_id is null then
RANK() OVER (partition by department_ID order by manager_id nulls first,employee_id)
end as sequenc
FROM (
SELECT 'radmon1' AS UUID,'finance' AS DEPARTMENT_ID,'employee1' AS EMPLOYEE_ID,'' AS MANAGER_ID,'John B' AS FIRST_NAME from dual UNION ALL
SELECT 'radmon2','finance','employee2','employee1','Michal' from dual UNION ALL
SELECT 'radmon3','finance','employee3','employee1','Ronaldo' from dual UNION ALL
SELECT 'radmon4','finance','employee4','employee1','Thomas' from dual UNION ALL
SELECT 'radmon5','finance','employee5','','Percey' from dual UNION ALL
SELECT 'radmon6','account','employee6','','Stacy' from dual UNION ALL
SELECT 'radmon7','account','employee7','','Jordan' from dual UNION ALL
SELECT 'radmon8','account','employee8','employee6','Micky' from dual UNION ALL
SELECT 'radmon9','account','employee9','employee6','Author' from dual UNION ALL
SELECT 'radmon10','account','employee10','employee6','Gordan' from dual
)d1;

I am trying to find a way to handle error 1062 of duplicate entries of '1' for key 'movieID'

I am trying to find a way to have duplicate value for key 1 to store in multiple genre for movieID.
I already tried auto increment on the table but still had those errors
CREATE TABLE movie_genres (
movieID INT NOT NULL AUTO_INCREMENT,
genre VARCHAR(50) NOT NULL,
PRIMARY KEY (movieID),
FOREIGN KEY (movieID) REFERENCES movies(ID)
);
ERROR 1062: 1062: Duplicate entry '1' for key 'movieID'
SQL Statement:
INSERT INTO movie.movie_genres (movieID, genre) VALUES ('1', 'Animation')
ERROR 1062: 1062: Duplicate entry '1' for key 'movieID'
SQL Statement:
INSERT INTO movie.movie_genres (movieID, genre) VALUES ('1', 'Children')
ERROR 1062: 1062: Duplicate entry '1' for key 'movieID'
SQL Statement:
INSERT INTO movie.movie_genres (movieID, genre) VALUES ('1', 'Comedy')
ERROR 1062: 1062: Duplicate entry '1' for key 'movieID'
SQL Statement:
INSERT INTO movie.movie_genres (movieID, genre) VALUES ('1', 'Fantasy')
Your database design has some fundamental problems, in particular it is missing a junction table which relates movies to their genres (1 to n). Here is one proposal for what your schema might be:
CREATE TABLE movies (
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255)
);
CREATE TABLE genres (
ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
genre VARCHAR(255)
);
CREATE TABLE movie_genres (
movieID INT NOT NULL,
genreID INT NOT NULL,
PRIMARY KEY (movieID, genreID)
);
Now with this schema in place, here is what your inserts might look like:
INSERT INTO movies (ID, title) VALUES (1, 'Avatar');
INSERT INTO genres (ID, genre)
VALUES
(1, 'Animation'), (2, 'Children'), (3, 'Comedy'), (4, 'Fantasy');
INSERT INTO movie_genres (movieID, genreID)
VALUES
(1, 1), (1, 2), (1, 3), (1, 4);
The basic idea here is that the movies and genres tables exist only to keep track of...movies and genres. They don't "know" anything about each other. To handle the relationships between movies and genres, your updated movie_genres table comes into play. It stores only the IDs from the movies and their corresponding genres.
This is how my schema looks like:
CREATE TABLE movies (
id INT NOT NULL,
title VARCHAR(180) NOT NULL,
imdbID VARCHAR(30),
spanishTitle VARCHAR(180),
imdbPictureURL VARCHAR(2200),
year VARCHAR(5),
rtID VARCHAR(150),
rtAllCriticsRating INT,
rtAllCriticsNumReviews INT,
rtAllCriticsNumFresh INT,
rtAllCriticsNumRotten INT,
rtAllCriticsScore INT,
PRIMARY KEY (id)
);
CREATE TABLE movie_genres (
movieID INT NOT NULL AUTO_INCREMENT,
genre VARCHAR(50) NOT NULL,
PRIMARY KEY (movieID),
FOREIGN KEY (movieID) REFERENCES movies(ID)
);

how to extract source table using sql?

I'm trying to write a query that extracts and transforms data from a table and then insert those data into target table and that whole table data should be in single column in target table.below is the query i wrote
INSERT INTO Table2(column1) VALUES
(SELECT * FROM Table1);
table 1
id | ename | email | country |
1 d .. ..
2 v .. ..
3 s .. ..
4 n .. ..
in table2
src_data | src_column | src_tablename
1 eid
2 eid
3 eid
4 eid
d ename
v ename
s ename
n ename
email1 email
email2 email
email3 email
email4 email
country1 country
country2 country
country3 country
country4 country
how can i achieve this ...can you plz suggest me to get this
This:
INSERT INTO table2
SELECT id, 'id', 'table1' FROM table1
UNION SELECT ename, 'ename', 'table1' FROM table1
UNION SELECT email, 'email', 'table1' FROM table1
UNION SELECT country, 'country', 'table1' FROM table1
uses hardcoded names of the columns and the table.

Get inserted row to Oracle with java

I am building a java program to insert data to my oracle database.
My problem is that I need to insert into two tables, and to reach unique rows I use in TABLE_A triggers for id before insert get next val in a sequence.
But i need the same id for the TABLE_B for connection.
( i cant get getval because what if another user uses the program... )
So I need to reach somehow that when I use executeql(sql) command in return I see what I have submit.
Now I use that I have name and date, so I select the id where name and date is the just inserted.
But its not the best because in one day I can insert more names. So now this will not unique.
like :
insert into table a ( name,date) val ( 'Ryan','2014.01.01')
id here is autoincremented by sequence
than another sql run:
inert into table_b ( id,someval) val ( select id from table_a where
name ='Ryan', date='2014.01.01, 23)
so i need something like:
system.out.println(smtp.executesql(sql).whatIinsertednow())
*than console:* '1 row insered (id,name,date) : ( 1, Ryan, 2014.01.01)
PreparedStatement prepareStatement = connection.prepareStatement("insert...",
new String[] { "your_primary_key_column_name" });
prepareStatement.executeUpdate();
ResultSet generatedKeys = prepareStatement.getGeneratedKeys();
if (null != generatedKeys && generatedKeys.next()) {
Long primaryKey = generatedKeys.getLong(1);
}
I have found the answer this is perfectly works. I can insert from JAVA and its return with the key.
Full version:
CREATE TABLE STUDENTS
(
STUDENT_ID NUMBER NOT NULL PRIMARY KEY,
NAME VARCHAR2 (50 BYTE),
EMAIL VARCHAR2 (50 BYTE),
BIRTH_DATE DATE
);
CREATE SEQUENCE STUDENT_SEQ
START WITH 0
MAXVALUE 9999999999999999999999999999
MINVALUE 0;
And the Java code
String QUERY = "INSERT INTO students "+
" VALUES (student_seq.NEXTVAL,"+
" 'Harry', 'harry#hogwarts.edu', '31-July-1980')";
// load oracle driver
Class.forName("oracle.jdbc.driver.OracleDriver");
// get database connection from connection string
Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:sample", "scott", "tiger");
// prepare statement to execute insert query
// note the 2nd argument passed to prepareStatement() method
// pass name of primary key column, in this case student_id is
// generated from sequence
PreparedStatement ps = connection.prepareStatement(QUERY,
new String[] { "student_id" });
// local variable to hold auto generated student id
Long studentId = null;
// execute the insert statement, if success get the primary key value
if (ps.executeUpdate() > 0) {
// getGeneratedKeys() returns result set of keys that were auto
// generated
// in our case student_id column
ResultSet generatedKeys = ps.getGeneratedKeys();
// if resultset has data, get the primary key value
// of last inserted record
if (null != generatedKeys && generatedKeys.next()) {
// voila! we got student id which was generated from sequence
studentId = generatedKeys.getLong(1);
}
}
source : http://viralpatel.net/blogs/oracle-java-jdbc-get-primary-key-insert-sql/
You can accomplish that by using the RETURNING clause in your INSERT statement:
INSERT INTO table_a ( name,date) val ( 'Ryan','2014.01.01') RETURNING id INTO ?

SQL Query to generate Employee absent report for a given range of dates

I Have two tables Master(empname,empid) which consists of all the employees and another table Transaction(empid,Presentdate) which gives the dates and which employee was present.
How do i find the list of absentees within a certain range of dates
I've tried the below Sql Query
SELECT empid FROM Master
where empid NOT IN(select empid from Transaction
where Date(Presentdate) between '2012-11-21' and '2012-12-22')
which returns only the employee id's who were absent,I want to display the employee's absent dates also
Note(Transaction table stores only the employee's present dates)
If an employee is absent then Entire record will not be inserted into the Transaction table
This should work, untested
SELECT m.empid AS `Empid`
, d.dt AS `AbsentDate`
FROM ( SELECT DATE(t.Presentdate) AS dt
FROM transaction t
WHERE t.Presentdate >= '2012-11-21'
AND t.Presentdate < DATE_ADD( '2012-12-22' ,INTERVAL 1 DAY)
GROUP BY DATE(t.Presentdate)
ORDER BY DATE(t.Presentdate)
) d
CROSS
JOIN master m
LEFT
JOIN transaction p
ON p.Presentdate >= d.dt
AND p.Presentdate < d.dt + INTERVAL 1 DAY
AND p.empid = m.empid
WHERE p.empid IS NULL
ORDER
BY m.empid
, d.dt
Not tested this, but this might work:
SELECT m.empid,d.Presentdate
FROM Master as m,
(select distinct Presentdate from transaction
where Date(Presentdate) between '2012-11-21' and '2012-12-22') as d
where m.empid not in (select empid from Transaction
where Presentdate=d.Presentdate)
// i suppose your query will like this to get employee name, id and day in which he/she is present.
select empid,empname,date from Transaction LEFT JOIN Master ON empid
where Date(Presentdate) between '2012-11-21' and '2012-12-22'
// for looping purpose created an array. You will be having emp id and name also
$array = array('2012-01-01','2012-01-02','2012-01-03','2012-01-05');
$date = new DateTime('2012-01-01'); // take first as start date
$startDate = $array[0];
$endDate = $array[count($array)-1];
$loop = 'yes';
while($loop == 'yes') {
$date->add(new DateInterval('P1D')); //add one day to start date
if(!in_array($date->format('Y-m-d'),$array))
$absentDate = $date->format('Y-m-d');
if($date->format('Y-m-d') == $endDate)
$loop = 'no';
}
print_r($absentDate);

Categories