SQLite select row with multiple condition from other table - sqlite

I'm having probleme with a SQL request.
I have two tables:
main table is
Id | Name
1 | Name_1
2 | Name_2
keyword table
Id | _mainId | key
1 | 1 | kw1
2 | 1 | kw2
3 | 1 | kw3
4 | 2 | kw2
5 | 2 | kw4
I would like a request which return the Id and Name of the mane table with all the keywords selected
something like this :
SELECT DISTINCT(t1.Id), t1.Name
FROM main t1
INNER JOIN keywords t2 ON t2._Main = t1.Id
WHERE t2.keyword = 'kw2' AND t2.keyword = 'kw4';

In the query below, the subquery aliased as t2 identifies all IDs having both the keywords 'kw2' and 'kw4'. I then join the main table to this subquery to bring in the name information for those matching IDs.
SELECT t1.Id, t1.Name
FROM main t1
INNER JOIN
(
SELECT _mainId
FROM keywords
WHERE keyword IN ('kw2', 'kw4')
GROUP BY _mainId
HAVING COUNT(DISTINCT keyword) = 2
) t2
ON t1.Id = t2._mainId

Try this:
SELECT DISTINCT
t1.Id, t1.Name
FROM
main t1
INNER JOIN keywords t2 ON t2._mainId=t1.Id
WHERE
t2.key IN ('kw2', 'kw4');

Related

SQLite - Merge 2 tables according to modified date, insert a new row if necessary

I have a table having an ID column, this column is a primary key and unique as well. In addition, the table has a modified date column.
I have the same table in 2 databases and I am looking to merge both into one database. The merging scenario in a table is as follows:
Insert the record if the ID is not present;
If the ID exists, only update if the modified date is greater than that of the existing row.
For example, having:
Table 1:
id | name | createdAt | modifiedAt
---|------|------------|-----------
1 | john | 2019-01-01 | 2019-05-01
2 | jane | 2019-01-01 | 2019-04-03
Table 2:
id | name | createdAt | modifiedAt
---|------|------------|-----------
1 | john | 2019-01-01 | 2019-04-30
2 | JANE | 2019-01-01 | 2019-04-04
3 | doe | 2019-01-01 | 2019-05-01
The resulting table would be:
id | name | createdAt | modifiedAt
---|------|------------|-----------
1 | john | 2019-01-01 | 2019-05-01
2 | JANE | 2019-01-01 | 2019-04-04
3 | doe | 2019-01-01 | 2019-05-01
I've read about INSERT OR REPLACE, but I couldn't figure out how the date condition can be applied. I know as well that I can loop through each pair of similar row and check the date manually but this would be very time and performance consuming. Therefore, is there an efficient way to accomplish this in SQLite?
I'm using sqlite3 on Node.js .
The UPSERT notation added in Sqlite 3.24 makes this easy:
INSERT INTO table1(id, name, createdAt, modifiedAt)
SELECT id, name, createdAt, modifiedAt FROM table2 WHERE true
ON CONFLICT(id) DO UPDATE
SET (name, createdAt, modifiedAt) = (excluded.name, excluded.createdAt, excluded.modifiedAt)
WHERE excluded.modifiedAt > modifiedAt;
First create the table Table3:
CREATE TABLE Table3 (
id INTEGER,
name TEXT,
createdat TEXT,
modifiedat TEXT,
PRIMARY KEY(id)
);
and then insert the rows like this:
insert into table3 (id, name, createdat, modifiedat)
select id, name, createdat, modifiedat from (
select * from table1 t1
where not exists (
select 1 from table2 t2
where t2.id = t1.id and t2.modifiedat >= t1.modifiedat
)
union all
select * from table2 t2
where not exists (
select 1 from table1 t1
where t1.id = t2.id and t1.modifiedat > t2.modifiedat
)
)
This uses a UNION ALL for the 2 tables and gets only the needed rows with EXISTS which is a very efficient way to check the condition you want.
I have >= instead of > in the WHERE clause for Table1 in case the 2 tables have a row with the same id and the same modifiedat values.
In this case the row from Table2 will be inserted.
If you want to merge the 2 tables in Table1 you can use REPLACE:
replace into table1 (id, name, createdat, modifiedat)
select id, name, createdat, modifiedat
from table2 t2
where
not exists (
select 1 from table1 t1
where (t1.id = t2.id and t1.modifiedat > t2.modifiedat)
)

How to get ID from table A to table B in trigger?

I have two tables, A & B:
TABLE A
id | name
TABLE B
id | name | fk_idA
I want to create trigger AFTER INSERT in TABLE B which updates fk_idA appropriate with the newest id from table A.
An example:
TABLE A
id | name
1 | Andrew
2 | David
TABLE B
id | name | fk_idA
1 | Photo1 | 2
If the ID column is autoincrementing, the latest is the largest one, i.e., the one returned by MAX:
CREATE TRIGGER DefaultAIsLatest
AFTER INSERT ON TableB
FOR EACH ROW
WHEN NEW.fk_idA IS NULL
BEGIN
UPDATE TableB
SET fk_idA = (SELECT MAX(id)
FROM TableA)
WHERE id = NEW.id;
END;

How to get list of Mutual friends,Following and Followers

I read many questions here about mutual friends and following and followers but i can't solved my problem, I have two tables like these.
User_table ( UID, Name)
Relation_table (RID, UID,UIDF)
for example in user_table have 4 users
UID | Name
------------------
1 | Kim Tessman
2 | Nella Ohler
3 | Adria Larose
4 | Huey Errico
And Relation_table have these data
RID | UID | UIDF
------------------
1 | 1 | 2
2 | 2 | 1
3 | 1 | 4
4 | 4 | 3
5 | 4 | 1
my questions are :
how to get list of Mutual friends ?
how to get list of Following ?
how to get list of Followers ?
please who can solve this problem thank you :)
I am guessing that the UID column in the Relation_Table is the user and that the UIDF is the person they are following. Here is the SQL query that finds who a person is following. The who is being followed is the same query, you just focus on the other name column or switch the column order around.
Here is a list of who follows who. It is also the list of who is being followed.
SELECT FollowingUser.UID as FollowingUserID, FollowingUser.Name, BeingFollowed.UID AS BeingFollowedID, BeingFollowed.Name AS BeingFollowedName
FROM User_table AS FollowingUser INNER JOIN
Relation_Table AS r ON FollowingUser.UID = r.uid INNER JOIN
User_table AS BeingFollowed ON r.uidf = BeingFollowed.UID
And this query gives you the list of mutual friends - but it gives the inverse of the relationship. If this matters, add this to the end where FollowingUser.UID > BeingFollowed.UID
SELECT FollowingUser.UID AS FollowingUserID, FollowingUser.Name, BeingFollowed.UID AS BeingFollowedID, BeingFollowed.Name AS BeingFollowedName
FROM User_table AS FollowingUser INNER JOIN
Relation_Table AS r ON FollowingUser.UID = r.uid INNER JOIN
Relation_Table AS r1 ON r.uid = r1.uidf AND r.uidf = r1.uid INNER JOIN
User_table AS BeingFollowed ON r1.uid = BeingFollowed.UID

Suggestion needed writing a complex query - sqlite

I have 4 columns in a table called musics - 'artist','genre', 'writer' , 'producer'.
I need to write a query such that, it returns a value 0 , if there are no repetition of values corresponding to the column name; if there is a repetition of values, it should return a value 1, corresponding to that column name.
Any help is much appreciated
SELECT (COUNT(artist) <> COUNT(DISTINCT artist)) artist,
(COUNT(genre) <> COUNT(DISTINCT genre)) genre,
(COUNT(writer) <> COUNT(DISTINCT writer)) writer,
(COUNT(producer) <> COUNT(DISTINCT producer)) producer
FROM musics
Another version
SELECT
( SELECT (COUNT(*) > 0)
FROM (SELECT 1 FROM musics GROUP BY artist HAVING COUNT(*) > 1) a
) artist,
( SELECT (COUNT(*) > 0)
FROM (SELECT 1 FROM musics GROUP BY genre HAVING COUNT(*) > 1) g
) genre,
( SELECT (COUNT(*) > 0)
FROM (SELECT 1 FROM musics GROUP BY writer HAVING COUNT(*) > 1) w
) writer,
( SELECT (COUNT(*) > 0)
FROM (SELECT 1 FROM musics GROUP BY producer HAVING COUNT(*) > 1) p
) producer
Sample data
| artist | genre | writer | producer |
------------------------------------------
| artist1 | genre1 | writer1 | producer1 |
| artist2 | genre2 | writer1 | producer2 |
| artist1 | genre3 | writer3 | producer3 |
Sample output:
| artist | genre | writer | producer |
--------------------------------------
| 1 | 0 | 1 | 0 |
SQLFiddle
For Artist
select convert(bit,(count(1)-1))
from table_name
group by artist -- <-- Replace artist with column name for which duplicate
write a select count statement using distinct with specified column and another select count without distinct and compare both of them based on your requirement
you can use 4 different query with union & each query must contain count(column name) + group by clause

SQLite Select data from multiple rows returned as one row

I would like to know whether it is possible to use a SELECT statement in SQLite to merge the data from two rows into one, similar to how is suggested in the SQL Server forum below.
Consider the scenario below which is based on SQL Server (taken from http://forums.aspfree.com/microsoft-sql-server-14/merge-the-two-rows-in-one-row-245550.html)
Given there is a table
Emp
ID | Name |
1 | x |
1 | P |
2 | y |
2 | Q |
3 | W |
We want the resulting data from the select statement to output:
Emp_Data
Id | Name-1 | Name-2 |
1 | x | P |
2 | y | Q |
3 | w | |
The answer in the post suggests the following SQL as a possible solution:
SELECT
a.ID,
[Name-1] = ISNULL((
SELECT TOP 1 Name
FROM emp
WHERE ID = a.ID),''),
[Name-2] = ISNULL((
SELECT TOP 1 b.Name
FROM emp b
WHERE b.ID = a.ID
AND Name NOT IN(
SELECT TOP 1 Name
FROM emp
WHERE ID = b.ID
)),'')
FROM emp a
GROUP BY a.ID
Using SQLite is it possible to generate the columns [Name-1] & [Name-2] using nested SELECT statements like we can do above in SQL Server?
SELECT
a.ID,
COALESCE(a.Name,'') as "Name-1",
COALESCE((SELECT b.Name FROM Emp b
WHERE b.ID = a.ID
AND b.rowid != a.rowid LIMIT 1),'') as "Name-2"
FROM emp a
GROUP BY a.ID
Doug's solution didn't work for me. The code below, however, did work for me but it's very slow...
SELECT
a.ID,
a.Name AS Name1,
(SELECT b.Name FROM Emp b
WHERE b.ID = a.ID
AND b.Name != a.Name LIMIT 1) AS Name2
FROM emp a
GROUP BY a.ID
try this:::
select id, group_concat(name) from emp group by id;
;)

Resources