I am trying to execute an SQLite query to update a column in my accounts table:
UPDATE account SET accrued = (account.accrued + ((product.intrate/365)*balance))
FROM account
JOIN customer ON customer.custid = account.custid
JOIN product ON product.prodid = account.prodid
WHERE active = 1
I have tried this, but it comes up with the result
ambiguous column name: account.accrued
UPDATE a SET accrued = (a.accrued + ((p.intrate/365)*balance))
FROM account a
JOIN customer c ON c.custid = a.custid
JOIN product p ON p.prodid = a.prodid
WHERE active = 1
I have also tried that query, but the result comes up with no such table a. If I take out the column accrued from the calculation I then get the same error for the balance column.
The column accrued is only in the one table, account.
This is the correct syntax for SQLite:
UPDATE account AS a
SET accrued = (a.accrued + ((p.intrate/365)*balance))
FROM customer c JOIN product p
ON p.prodid = a.prodid
WHERE c.custid = a.custid AND active = 1
Note that you should qualify all the column names (except the column that is updated after SET) with the table name/alias to avoid ambiguities.
Related
Table rental has values (ID, odo_out, date),
table vehicle has values (ID, odo, car),
both with more columns but not relevant to this.
I have attempted to create a trigger:
CREATE TRIGGER odo_update AFTER INSERT ON rental
BEGIN
UPDATE rental SET odo_out = (SELECT Vehicle.odo FROM Vehicle WHERE rental.ID = Vehicle.ID)
WHERE EXISTS (SELECT * FROM Vehicle WHERE Vehicle.ID = rental.ID);
END;
which should detect a NULL for rental.odo_out and replace it with the value in Vehicle.odo for corresponding ID. This does work, but it updates every row in table, whereas I want it to ONLY update the row with NULL, ie the new row being inserted. An ID can be repeated multiple times in the rental table. How can I do this?
You must set the condition so that only the new row is updated.
This is where you need the keyword NEW to refer to the columns of the new row:
CREATE TRIGGER odo_update AFTER INSERT ON rental
WHEN NEW.odo_out IS NULL
BEGIN
UPDATE rental
SET odo_out = (SELECT odo FROM Vehicle WHERE ID = NEW.ID)
WHERE ID = NEW.ID;
END;
I am trying out SQLite and encountered a problem. There are 3 Tables A, B, and C.
I want to update Table A using the sum of B and C.
Table A.
James null.
Table B.
James 5.
Table C
James 2
so with the update, I want table A to have
James 3. (5-2)
Thank You
SQLite does not support joins in an UPDATE statement so you can do it by accessing directly the corresponding rows of the tables A and B like this:
update A
set value =
(select value from B where name = A.name) -
(select value from C where name = A.name)
If you want to update only the row with name = 'James' then add:
where name = 'James'
See the demo
Works in every DB:
UPDATE
"A"
SET
"x" =
(
SELECT
SUM("x")
FROM "B"
WHERE "B"."id"="A"."id"
) +
(
SELECT
SUM("x")
FROM "C"
WHERE "C"."id"="A"."id"
)
I believe the following demonstrates that Yes you can:-
DROP TABLE IF EXISTS ta;
DROP TABLE IF EXISTS tb;
DROP TABLE IF EXISTS tc;
CREATE TABLE IF NOT EXISTS ta (name TEXT, numb INTEGER);
CREATE TABLE IF NOT EXISTS tb (name TEXT, numb INTEGER);
CREATE TABLE IF NOT EXISTS tc (name TEXT, numb INTEGER);
INSERT INTO ta VALUES ('JAMES',null),('Mary',100);
INSERT INTO tb VALUES ('JAMES',5),('Sue',33);
INSERT INTO tc VALUES ('JAMES',2),('Anne',45);
UPDATE ta SET numb =
(SELECT sum(numb) FROM tb WHERE name = 'JAMES')
-
(SELECT sum(numb) FROM tc WHERE name = 'JAMES')
WHERE name = 'JAMES';
SELECT * FROM ta;
SELECT * FROM tb;
SELECT * FROM tc;
This :-
Drops the tables if they exist allowing it to be rerun (simplifies modifications if need be).
column names name and numb have been assumed as they weren't given.
Creates the 3 tables (note table names used for the demo are ta, tb and tc)
Adds some data (note that additional rows have been added to show how to distinguish (at least to a fashion))
Updates column numb of table A (ta) where the name column has a value of JAMES according to the sum of the numb column from all rows with the same name (JAMES) from table tb minus the sum of the numb column from all rows with the same name (JAMES) from table tc
This may not be exactly what you want so it assumes that you want to sum all rows with the same name per table (ta and tc)
Queries all the tables (first is shown below as that is the table that has been updated.)
The first result showing that the row has been updated from null to 3 (5 - 2) and that the row for Mary has remained as it was :-
The following change to the UPDATE gets the name (rather than hard-coding 'JAMES' multiple times, as per the row(s) extract from the ta table, the use of hard-coded names perhaps making it easier to understand the working of the SQL).
UPDATE ta SET numb = (SELECT sum(numb) FROM tb WHERE name = ta.name) - (SELECT sum(numb) FROM tc WHERE name = ta.name) WHERE name = 'JAMES';
Note that should there not be an associated row (i.e. with the same name) in either tb or tc then the result will be null (whether or not sum is used).
I am fetching data from SQLite database using following query:
SELECT p.sent,
e.*,
e.no _id
FROM ecare e
LEFT OUTER JOIN pweb p ON e.h_id = p.h_id
WHERE (ant = 'N' or ant = 'D')
GROUP BY e.h_id
ORDER BY p.sent
By using the above SQLite query, I am getting all the records belonging to sent (where sent = 1 and sent = 0).
Now, I would like to get only those records from database, where sent status is sent = 0. (In short, I don't want to fetch all the records belonging to sent, or records where sent = 1).
Have you tried with below query ?
SELECT p.sent,e.*, e.no _id from ecare e LEFT JOIN pweb p ON
e.h_id=p.h_id WHERE (ant = 'N' or ant = 'D') AND p.sent = '0' GROUP
BY e.h_id
Check below query for your question:
return db.rawQuery("SELECT p.sent,e.*, e.no _id from ecare e LEFT OUTER JOIN pweb p ON e.h_id=p.h_id WHERE (ant = 'N' or ant = 'D') AND p.sent = '1' GROUP BY e.h_id ORDER BY p.sent ", null);
You are already filtering on the ant column.
Adding a filter for sent works the same way:
SELECT ...
...
WHERE (ant = 'N' OR ant = 'D')
AND sent = 0
...
I need to select data from four tables based on only one.
In my 'calculated' table, I have all the records I need.
But I need to retrieve some other info for each record, from 'programs', 'term' and 'imported' tables.
'calculated' has ID from 'programs'.
But, to achieve a record from 'imported', I need to join the 'item' table, because 'item' has ID from 'programs' and from 'imported'.
'term' has ID from 'imported'.
So, I tried this:
select c.date,
p.name,
c.name1,
c.name2,
t.date,
i.version,
c.price1,
c.price2,
c.price3
from calculated c, programs p, term t, imported i, item it
where c.programs_id = p.programs_id
and c.programs_id = it.programs_id
and it.imported_id = i.imported_id
and i.term_id = t.term_id;
But when I use count(*) on 'calculated', I get 30k of records, and from my select statement I get more than 130 millions of records.
What am I doing wrong?
What should I do for this to work?
If all duplicates rows are equivalent, u can try smth like this
select c.date,
p.name,
c.name1,
c.name2,
t.date,
i.version,
c.price1,
c.price2,
c.price3
from calculated c, programs p, term t, imported i
where c.programs_id = p.programs_id and
(select imported_id from item it where c.programs_id = it.programs_id and rownum = 1) = i.imported_id
and i.term_id = t.term_id;
where "rownum = 1" is restriction on the selection of one line for oracle.
you forgot to join term table.
Probably you need to add
and t.term_id = i.term_id
I'm having difficulty with a query which displays records according to their fill rate.
For instance, a vacancy can have no bookings or some bookings. If a vacancy has bookings, they can be in the form of 'active [1]', 'pending [0]'. The query I have written so far works if the vacancy has booking records but I can't get it to work if it doesn't have booking records.
My query (which works) for vacancies with a booking is as follows:-
SELECT v.*, j.job_category_name, bu.business_unit_name
FROM vacancy v
INNER JOIN job_category j ON j.job_category_id = v.job_category_id
INNER JOIN business_unit bu ON bu.business_unit_id = v.business_unit_id
INNER JOIN booking b ON b.vacancy_id = v.vacancy_id
INNER JOIN booking_status bs ON bs.id = b.booking_status_id
WHERE
v.vacancy_status <> 'revoked' AND
v.vacancy_reference <> 'auto-generated booking' AND
v.business_unit_id IN (series of primary keys) AND
(bs.booking_status_type_id = 1 OR bs.booking_status_type_id = 2)
GROUP BY v.vacancy_id
HAVING v.vacancy_limit > count(b.booking_id)
ORDER BY v.vacancy_id DESC
I thought by changing the join of b and bs to LEFT JOIN would have worked, but it hasn't.
Any ideas?
Without a copy of your schema to work from, it's difficult to tell exactly, but when you changed booking and bookingstatus to LEFT JOINs, did you also modify your WHERE clause so that it read something like:
WHERE
v.vacancy_status <> 'revoked' AND
v.vacancy_reference <> 'auto-generated booking' AND
v.business_unit_id IN (series of primary keys) AND
(ISNULL(bs.booking_status_type_id, 1) = 1 OR ISNULL(bs.booking_status_type_id, 2) = 2)
i.e. Ensured that the full WHERE clause would be satisfied, thus not stripping out the records where all the values for columns from booking and bookingstatus were NULL?
Try LEFT OUTER JOIN for the tables for which the joins may return 0 matches.
For eg:- in your case have LEFT OUTER JOIN for b and bs and check