Sqlite query creating issue - mysql

There are 2 tables
table1 table2
book_id | tag_id tag_id
---------------- -----------
5 | 1 1
5 | 3 3
5 | 4 4
7 | 1
7 | 2
7 | 4
I need to create sql query for selection all book_id where tag_id is multitude of all tag_id from table2 (SQLite).
For example, book_id = 5 is acceptable because it has all tags from table2 (1, 3, 4).
The book with book_id = 7 isn't acceptable because it has only 1 and 4 tags, but hasn't tag_id = 3.

I'm not sure if this query will be very efficient, but...
select distinct book_id from table1 x
where not exists(
select * from table2 t where not exists(
select * from table1 a
where a.tag_id = t.tag_id
and a.book_id = x.book_id));
Setup code:
drop table table1;
drop table table2;
create table table1(book_id int, tag_id int);
insert into table1 values(5, 1);
insert into table1 values(5, 3);
insert into table1 values(5, 4);
insert into table1 values(7, 1);
insert into table1 values(7, 2);
insert into table1 values(7, 4);
create table table2(tag_id int);
insert into table2 values(1);
insert into table2 values(3);
insert into table2 values(4);

Related

Preferential Select Query

The issue that we are trying to tackle is best shown with the following illustrative example:
CREATE TABLE table_1
(
id INT UNSIGNED AUTO_INCREMENT,
colA INT,
colB VARCHAR(10),
PRIMARY KEY(id)
);
CREATE TABLE table_2
(
id INT UNSIGNED AUTO_INCREMENT,
colY INT,
colZ VARCHAR(10),
PRIMARY KEY(id)
);
INSERT INTO table_1(colA, colB) VALUES(1, 'NPD5A6V9EI'), (2, 'ISO4IK42YQ'), (4, 'J12QAN4O42'), (6,'V8YTZFHCU4');
INSERT INTO table_2(colY, colZ) VALUES(3, 'RBUNWLO753'), (4, 'X2BCEY7O8B'), (5, 'BNUS7R4225'), (6, '72NOWCTH5G');
We would like to select our result based on the value of colA in table_1 but if that does not return a result , we would like to return our result based on the value of colY in table_2. In other words SELECTing from table_2 is the backup for SELECTing from table_1. The query returns NULL only if neither table satisfies the condition.
A pseudo SQL query could be:
SELECT colB FROM table_1 where colA = 3 OR SELECT colZ FROM table_2 where colY = 3;
The query should return output based on the following I/O table:
I O
= =
1 NPD5A6V9EI -- From table_1
2 ISO4IK42YQ -- From table_1
3 RBUNWLO753 -- From table_2
4 J12QAN4O42 -- From table_1 (has precedence over table_2 entry)
5 BNUS7R4225 -- From table_2
6 V8YTZFHCU4 -- From table_1 (has precedence over table_2 entry)
9 NULL
Kindly suggest solutions that:
make use of the latest DB features (for posterity)
work with MySQL version 5.6.51 (for our application)
Write a subquery that generates all the I rows that you want.
Then left join this with the two tables, and use IFNULL to take the matching value from table_1 in preference to table_2.
SELECT ids.id AS I, IFNULL(t1.colB, t2.colZ) AS O
FROM (SELECT 1 AS id UNION ALL SELECT 2 UNION ALL SELECT 3 ... UNION ALL SELECT 9) AS ids
LEFT JOIN table_1 AS t1 ON t1.colA = ids.id
LEFT JOIN table_2 AS t2 ON t2.colY = ids.id
ORDER BY ids.id
I simply don't kn ow where you get your last row.
also with Myql 8 you can ise the window function ROW_NUMBER
the rest is self explantory, the sorting comes from colA and Col1, when there are teh same numbers the second column orderby2 comes and sorts first for the first table
CREATE TABLE table_1
(
id INT UNSIGNED AUTO_INCREMENT,
colA INT,
colB VARCHAR(10),
PRIMARY KEY(id)
);
CREATE TABLE table_2
(
id INT UNSIGNED AUTO_INCREMENT,
colY INT,
colZ VARCHAR(10),
PRIMARY KEY(id)
);
INSERT INTO table_1(colA, colB) VALUES(1, 'NPD5A6V9EI'), (2, 'ISO4IK42YQ'), (4, 'J12QAN4O42'), (6,'V8YTZFHCU4');
INSERT INTO table_2(colY, colZ) VALUES(3, 'RBUNWLO753'), (4, 'X2BCEY7O8B'), (5, 'BNUS7R4225'), (6, '72NOWCTH5G');
SELECT #i := #i +1 AS I,
colB AS O
FROM
(SELECT colA as orderby1,colB,1 ordberby2 froM table_1
UNION
SELECT colY, colZ,2 froM table_2 ) t1,(SELECT #i := 0) t2
ORDER BY orderby1,ordberby2
I | O
-: | :---------
1 | NPD5A6V9EI
2 | ISO4IK42YQ
3 | RBUNWLO753
4 | J12QAN4O42
5 | X2BCEY7O8B
6 | BNUS7R4225
7 | V8YTZFHCU4
8 | 72NOWCTH5G
db<>fiddle here

MySQL - 1 Master List Table Not IN Table 2 but IN Table 3

Can you kindly help me with my query?
In my database, I have 3 tables,
Table 1 - Student Master List (9 Records)
Table 2 - AM (4 Records)
Table 3 - PM (3 Records)
Table 2 and table 3 have the same structure but Table 2 is more priority than Table 3, anyway
I want to see the records from Table 1 which are NOT IN Table 2 BUT there's a record IN Table 3. Table 2 (4) + Table 3 (3) = 7 Records
But how can I show the 2 records from the master list
sample database
My query is something like this:
select * from table1 t1
where (id, lname, fname, mname) NOT IN
(select id, lname, fname, mname from table2) and
(id, lname, fname, mname) IN
(select id, lname, fname, mname from table3)
But when I did this, It just shows some records from table 2 and table 3
If you have a common key among all tables which is (id, lname, fname, mname) below will work. If your common key is somewhat different, adjust WHERE clauses in both subqueries to only include the common key (column(s)).
Use EXISTS to include records present in table 3 and NOT EXISTS to exclude records present in table 2:
select *
from table1 t1
where
not exists (
select 1
from table2 t2
where t1.id = t2.id and t1.lname = t2.lname and t1.fname = t2.fname and t1.mname = t2.mname)
and exists (
select 1
from table3 t3
where t1.id = t3.id and t1.lname = t3.lname and t1.fname = t3.fname and t1.mname = t3.mname)
I suspect you just need to union table 2 and 3 and left join table 1 testing for null values
drop table if exists t1,t2,t3;
create table t1 (id int);
create table t2 (id int);
create table t3 (id int);
insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
insert into t2 values (2),(3),(4),(5);
insert into t3 values (1),(6),(7);
select t1.*
from t1
left join
(select id from t2
union all
select id from t3)s on s.id = t1.id
where s.id is null;
+------+
| id |
+------+
| 8 |
| 9 |
+------+
2 rows in set (0.00 sec)

result of selection is array and I want to use it to "where in" another selection

I have two tables (t1 & t2):
t1 (second column is array)
name | code
ee | 123, 124, 125
ef | 121, 123
______________________
t2
code_id | code_desc
121 | xxxxx
123 | yyyyyyy
124 | xxxxxxxx
if I do this query, all is ok:
SELECT * FROM t2 where code_id in (121,122)
but if I do this query I got NULL cell / result
SELECT * FROM t2 where code_id in (SELECT code FROM t1 where name = ee)
How can I get from one query all the info from two table?
Here is the code, I cant find a good sql online tool
CREATE TABLE t1 (name VARCHAR(200), codes VARCHAR(200));
CREATE TABLE t2 (codes_id VARCHAR(200), codes_desc VARCHAR(200));
INSERT INTO t1 (name, codes) VALUES ('ee', '123,124,125');
INSERT INTO t1 (name, codes) VALUES ('ef', '121,124');
INSERT INTO t1 (name, codes) VALUES ('eh', '123,124,125');
INSERT INTO t2 (codes_id, codes_desc) VALUES ('121', 'yyyyyyyyy');
INSERT INTO t2 (codes_id, codes_desc) VALUES ('122', 'xxxxxxxxx');
INSERT INTO t2 (codes_id, codes_desc) VALUES ('123', 'zzzzzzzzzzz');
SELECT * FROM t2 where code_id in (121,122)
SELECT * FROM t2 where code_id in (SELECT codes FROM t1 where name = 'ee')
You can use find_in_set function:
select *
from t2
where exists (
select 1
from t1
where name = 'ee'
and find_in_set(t2.code_id, t1.code) > 0
)
I'll advise you to normalize your table structure though. Because even though the above query is working, it is non-sargable.

Question on multi-row insertion with subqueries

Say I have the following 2 tables,
CREATE TABLE t1(
name VARCHAR(25) NOT NULL,
time INT,
a INT
);
CREATE TABLE t2(
name VARCHAR(25) NOT NULL,
time INT,
b INT
);
and Im looking to pull all the values (a) out of t1 with a given time, all the values with the previous time (say just time-1 for convenience) then for each name subtract the newer one from the older one and insert those values into t2 with the same time. The slow way of doing this would involve doing something like
SELECT name, a FROM t1 WHERE time = x;
SELECT name, a FROM t1 WHERE time = x-1;
(subtract the as for each name)
INSERT INTO t2 VALUES ....;
From my (limited) understanding of subqueries, there should hopefully be a way to do this all in 1 query. Any ideas? Thanks in advance :)
It looks like you can use the INSERT ... SELECT syntax:
INSERT INTO t2 (name, time, b)
SELECT ta.name, ta.time time, (ta.a - tb.a) b
FROM t1 ta
JOIN t1 tb ON (tb.time = ta.time - 1 AND tb.name = ta.name);
Test case:
INSERT INTO t1 VALUES ('t1', 1, 100);
INSERT INTO t1 VALUES ('t1', 2, 200);
INSERT INTO t1 VALUES ('t1', 3, 500);
INSERT INTO t1 VALUES ('t1', 4, 600);
INSERT INTO t1 VALUES ('t1', 5, 800);
INSERT INTO t1 VALUES ('t1', 6, 900);
Result:
SELECT * FROM t2;
+------+------+------+
| name | time | b |
+------+------+------+
| t1 | 2 | 100 |
| t1 | 3 | 300 |
| t1 | 4 | 100 |
| t1 | 5 | 200 |
| t1 | 6 | 100 |
+------+------+------+
5 rows in set (0.00 sec)
there is im mysql insert ... select
INSERT INTO table ( fields )
SELECT fields FROM table;

Multiple delete in a single query

DELETE FROM Table1 WHERE ConditionID=?ConditionID;
DELETE FROM Table2 WHERE ConditionID=?ConditionID;
DELETE FROM Table3 WHERE ConditionID=?ConditionID;
ConditionID is a column present in Table1,Table2,Table3, instead of running 3 times individually, is there a way to run all the three in a single query (in mysql)?
If the ConditionID is the same for all the three tables, you should be able to use the Multiple Table Delete Syntax:
DELETE Table1, Table2, Table3
FROM Table1
JOIN Table2 ON (Table2.ConditionID = Table1.ConditionID)
JOIN Table3 ON (Table3.ConditionID = Table2.ConditionID)
WHERE Table1.ConditionID = ?;
Test case:
CREATE TABLE Table1 (id int, ConditionID int);
CREATE TABLE Table2 (id int, ConditionID int);
CREATE TABLE Table3 (id int, ConditionID int);
INSERT INTO Table1 VALUES (1, 100);
INSERT INTO Table1 VALUES (2, 100);
INSERT INTO Table1 VALUES (3, 200);
INSERT INTO Table2 VALUES (1, 100);
INSERT INTO Table2 VALUES (2, 200);
INSERT INTO Table2 VALUES (3, 300);
INSERT INTO Table3 VALUES (1, 100);
INSERT INTO Table3 VALUES (2, 100);
INSERT INTO Table3 VALUES (3, 100);
Result:
DELETE Table1, Table2, Table3
FROM Table1
JOIN Table2 ON (Table2.ConditionID = Table1.ConditionID)
JOIN Table3 ON (Table3.ConditionID = Table2.ConditionID)
WHERE Table1.ConditionID = 100;
SELECT * FROM Table1;
+------+-------------+
| id | ConditionID |
+------+-------------+
| 3 | 200 |
+------+-------------+
1 row in set (0.00 sec)
SELECT * FROM Table2;
+------+-------------+
| id | ConditionID |
+------+-------------+
| 2 | 200 |
| 3 | 300 |
+------+-------------+
2 rows in set (0.00 sec)
SELECT * FROM Table3;
Empty set (0.00 sec)
I don't know what your schema looks like, but if you use InnoDB, or a similar table engine for your tables and you have foreign keys, you can set conditions that will cause derived entries to be deleted when a parent entry is deleted. See http://dev.mysql.com/doc/refman/5.1/en/innodb-foreign-key-constraints.html for more info on that.
Nope. ConditionID is separate in each oneā€”just because it has the same name doesn't mean it's the same column. If you fully qualify the names, you'll be able to see it better:
DELETE FROM Table1 WHERE Table1.ConditionID=?ConditionID;
DELETE FROM Table2 WHERE Table2.ConditionID=?ConditionID;
DELETE FROM Table3 WHERE Table3.ConditionID=?ConditionID;
You can delete rows from multiple tables by just using mysql "delete" query.Consider,you've two tables profile and books.
Profile table consists,
id
name
books table consists,
pid
book
price
You can delete records from these two table for particular id by using this query,
delete profile,books from profile,books where profile.id=18 and profile.id=books.pid;