To INSERT a row into table from another table - sqlite

I have the 'SchoolYearTeachingDays' table with just one column, in which are dates:
CREATE TABLE SchoolYearTeachingDays (
aDate DATE PRIMARY KEY
UNIQUE
);
I filled it with many dates which are unique. These dates excludes dates for Sundays and for Saturdays.
I have another, the 'TeachingSaturdaysInSchoolYear' table:
CREATE TABLE TeachingSaturdaysInSchoolYear (
id INT PRIMARY KEY
UNIQUE,
aDate DATE,
TimetableForTheDay TEXT
);
This table holds just two dates. These two dates are for two Saturdays. On these two Saturdays we have to teach students.
When I do the following query on this table, I get these two records:
2018-04-14
2018-05-05
I want to INSERT these two dates from the 'TeachingSaturdaysInSchoolYear' table into 'SchoolYearTeachingDays' table.
I am trying with this query:
INSERT INTO SchoolYearTeachingDays
SELECT aDate FROM TeachingSaturdaysInSchoolYear
;
but I get this error:
Error: UNIQUE constraint failed: SchoolYearTeachingDays.aDate
How this query of mine works and why I get this error? How do I accomplish my goal?
Best, Pal

You are violating unique constraint by inserting duplicate values into the table SchoolYearTeachingDays.
To fix the error put a not in condition so that dates which are already inserted won't get inserted again into SchoolYearTeachingDays table.
Example,
INSERT INTO SchoolYearTeachingDays
SELECT aDate FROM TeachingSaturdaysInSchoolYear T WHERE T.aDate NOT IN (SELECT S.aDate FROM SchoolYearTeachingDays S)

Related

Inserting rows from table2 to end of table1 with unique ids

I'm trying to add a test user to my website that employers can look at to see my work. I want to use some of the data I have entered into my profile so that it is faster.
I have a workouts table:
CREATE TABLE workouts(
id INTEGER NOT NULL,
userID INTEGER NOT NULL,
DateAndTime smalldatetime NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (UserID) REFERENCES users(id)
);
I have taken 25 of the first results and put it into a temporary workouts2 table:
CREATE TABLE workouts2 (
userid integer,
dateandtime smalldatetime);
Now I want to take those rows from workouts2 and put them into workouts. I have tried to add them by inserting workouts2 into workouts like this:
insert into workouts (id , userID, DateandTime) values (select * from workouts2);
This gives me an Error: in prepare, near "select": syntax error (1)
I can do it one at a time like this:
insert into workouts (userid, dateandtime) values (2, "2022-01-02T06:00");
Doing it one at a time is not ideal.
What am I missing here? I know I have a syntax error but I don't know how to fix it.
I have looked at this question which inserts one at a time:
How to insert a unique ID into each SQLite row?
The problem is it only inserts one at a time.
You should use SELECT instead of VALUES and not include the column id, which is auto-incremented, in the list of columns of workouts which will receive the values (such a column does not exist in workouts2):
INSERT INTO workouts (userID, DateandTime)
SELECT *
FROM workouts2;

SQL error or missing database (near "," syntax error)

I have this query with syntax error. Can you help me find the error please?
I spend couple of hour and I can't solve it. Thanks.
String sql = " INSERT INTO appointments (patient_firstname, patient_surname, fees, time, date, doctor)"
+ " SELECT (time, date, doctor)"
+ " WHERE NOT EXISTS (SELECT * FROM appointments WHERE time = ?)";
pst=conn.prepareStatement(sql);
pst.setString(1,txt_firstname.getText());
pst.setString(2,txt_surname.getText());
pst.setString(3, txt_fee.getText());
pst.setString(4, (String) cbox_time.getSelectedItem());
pst.setString(5,txt_date.getText());
pst.setString(6, (String) cbox_doctors.getSelectedItem());
pst.executeUpdate();
The issues with your INSERT statement includes :-
You appear to be attempting an INSERT SELECT where the VALUES to be inserted are obtained from the SELECT clause, but you are trying to mix this with VALUES. The two types cannot be combined.
You are trying to select using columns within parenthesises and anyway those three columns WILL NOT match the 6 columns required for the insert.
You only have 1 ? to be bound, you are trying to bind 6.
I'd suggest that you could simplify matters by defining the table with a UNIQUE constraint on the doctor, date and time columns. Then use a standard INSERT OR IGNORE with the VALUES clause.
e.g. consider the following demonstration SQL :-
DROP TABLE IF EXISTS appointments;
CREATE TABLE IF NOT EXISTS appointments (patient_firstname TEXT, patient_surname TEXT, fees REAL, time TEXT, date TEXT, doctor INTEGER, UNIQUE (doctor, date, time));
INSERT OR IGNORE INTO appointments VALUES ('Fred','Bloggs',100.50,'10:00','2019-01-01',1);
INSERT OR IGNORE INTO appointments VALUES ('Mary','Smith',100.50,'10:00','2019-01-01',2);
INSERT OR IGNORE INTO appointments VALUES ('Sue','Bell',100.50,'10:00','2019-01-01',2);
SELECT * FROM appointments;
This results in :-
i.e Sue Bell's appointment has not been added because of the UNIQUE constraint conflict, which has been ignored so there is no error.
The log being :-
DROP TABLE IF EXISTS appointments
> OK
> Time: 0.177s
CREATE TABLE IF NOT EXISTS appointments (patient_firstname TEXT, patient_surname TEXT, fees REAL, time TEXT, date TEXT, doctor INTEGER, UNIQUE (doctor, date, time))
> OK
> Time: 0.084s
INSERT OR IGNORE INTO appointments VALUES ('Fred','Bloggs',100.50,'10:00','2019-01-01',1)
> Affected rows: 1
> Time: 0.083s
INSERT OR IGNORE INTO appointments VALUES ('Mary','Smith',100.50,'10:00','2019-01-01',2)
> Affected rows: 1
> Time: 0.084s
INSERT OR IGNORE INTO appointments VALUES ('Sue','Bell',100.50,'10:00','2019-01-01',2)
> Affected rows: 0
> Time: 0s
SELECT * FROM appointments
> OK
> Time: 0.003s

SQLite check for duplicate rows

I have an SQLite database for an art exhibition. In the table "exhibits" I have columns for the artwork ID, the exhibition space ID, a begin date, and an end date. The default value for "end date" is NULL.
Of course, the same artwork cannot be displayed in two different spaces at once. So I want to ensure that a new row with an artwork ID is not created unless all existing rows with that same artwork ID have a non-null end date.
Is there some kind of constraint, trigger, etc. that I can add to the table to ensure this?
I am not an expert on writing triggers for SQLite but something like this should work,
CREATE TRIGGER check_open_ended_exhibit BEFORE INSERT ON exhibits
BEGIN
SELECT RAISE(ABORT, "Open ended exhibit exists")
WHERE EXISTS(SELECT * FROM exhibits WHERE artworkID = NEW.artworkID AND enddate IS NULL);
END
According to your information “Artwork” cannot be displayed twice in the same show which means the EndTime is a unique field when constraining it together with Artwork. So by making these two together your constrain you won’t be able to insert a record if you already have “artwork and NULL”.
So yeah you can just create a unique constrain on these two columns.
CREATE TABLE testConstrain (
id INTEGER NOT NULL,
endDate DATETIME
)
CREATE UNIQUE INDEX testConstrain
ON testConstrain(id, endDate);
INSERT INTO testConstrain VALUES('1',null)
INSERT INTO testConstrain VALUES('2','01-01-2018')
INSERT INTO testConstrain VALUES('1','01-01-2018')
INSERT INTO testConstrain VALUES('1',null)
`
And you will get:
Started executing query at Line 11
(1 row affected)
(1 row affected)
(1 row affected)
Msg 2601, Level 14, State 1, Line 4
Cannot insert duplicate key row in object 'bginsburg.testConstrain' with unique index 'testConstrain'. The duplicate key value is (1, ).
The statement has been terminated.

SQLite search two tables

In a SQLite database, I have created two tables:
CREATE Table Master (ItemID VARCHAR PRIMARY KEY, Property VARCHAR)
CREATE Table Counter (OtherID VARCHAR PRIMARY KEY, ItemID VARCHAR)
Records on table Master:
* ItemID: Book, Property: large
* ItemID: Table, Property: green
Records on table Counter:
* OtherID: random1, ItemID: Book
* OtherID: random2, ItemID: Book
* OtherID: random3, ItemID: Book
The column ItemID on table Master has the same contents as the same-named column on table Counter.
What is the correct SQL select statement to get all rows from table Master sorted by the number of their records in table Counter ?
In this case, row "Book" has three counts in table Counter and should be listed on first position, while row "Table" has no counts and should be the second result.
I know how to do this on one table but never managed to get a SQL select statement working that spans two tables.
Any help is appreciated.
By the way: I cannot change the table structure; so not sure if there would be something better, but I have to work with the tables as they are.
attach to two different databases
access tables with "db?." in front
join both tables on the common semantic, i.e. the ItemId
left join to get the "empty" lines, too, with "0" count
make groups which represent the lines you want in the output, i.e. also by ItemId
grouping allows using the aggregate function "count()"
order according to desired output, i.e. by count, but descending to get "3" first
select the ItemId and the property to match desired output
Code:
attach 'master.db' as dbm;
attach 'counter.db' as dbc;
select a.ItemId, property
from dbm.Master a LEFT JOIN dbc.Counter b
using (ItemId)
group by a.ItemId
order by count(OtherId) desc;
Tested with :
echo .dump | sqlite3 counter.db
BEGIN TRANSACTION;
CREATE TABLE Counter (OtherID VARCHAR PRIMARY KEY, ItemID VARCHAR);
INSERT INTO Counter VALUES('random1','book');
INSERT INTO Counter VALUES('random2','book');
INSERT INTO Counter VALUES('random3','book');
COMMIT;
echo .dump | sqlite3 master.db
BEGIN TRANSACTION;
CREATE TABLE Master (ItemID VARCHAR PRIMARY KEY, Property VARCHAR);
INSERT INTO Master VALUES('book','large');
INSERT INTO Master VALUES('table','green');
COMMIT;
Output:
book|large
table|green
If I understand you, I think this should work:
SELECT M.ItemId, Property
FROM Master M
LEFT JOIN Counter C
ON M.itemid=C.itemid
GROUP BY C.itemid
ORDER BY COUNT(C.itemid) DESC;

How to use a SQLite table's default values?

I'm looking to insert data into a column like so:
INSERT INTO Song values (null, 'Truth of a Liar')
into a table set up like this:
CREATE TABLE Song (id integer primary key, name varchar(255), count int not null default 0)
and I get the following error: table Song has 3 columns but 2 values were supplied INSERT INTO Song2 values (null, 'Truth of a Liar')
I was expecting be able to not put in the last column because I occasionally might have to put in the count value. I'm aware that I could explicitly fill the columns like so:
INSERT INTO Song(id, name) values (null, 'msdads')
but I was hoping for an alternative.
Is there another way to INSERT data into tables, using some default values and some set values?
You could do:
INSERT INTO Song values (null, 'Truth of a Liar',0)
when you do not want to insert anything for last column. When you want to occasionally insert a value, you can use that value instead of 0.

Resources