I am having two table
Table 1 having a field
id
book_ids
1
1,2,3
Table 2 have all the book Ids
select *
from table 2
where book_id in (select book_ids from table 1 where id=1) ;
this statement not returning all the book ids from table 2 having id 1,2,3
Can anyone help
You could use the FIND_IN_SET() function:
select *
from table 2
where FIND_IN_SET(book_id, (select book_ids from table 1 where id=1)) > 0;
Read the documentation I linked to for details on how that function works.
But only do this if your table remains small. Using this function spoils any opportunity to optimize the query with an index, so the larger your table gets, the performance will grow worse and worse.
Also FIND_IN_SET() doesn't work the way you expect if there are spaces in your comma-separated list.
try to store table1 values in rows of table not in a same field.
and then your SELECT IN works.
Related
I am playing around with ms-access (MS-Office Professional Plus 2013) trying to figure out if I have duplicate rows before I merge one table into another table. I want to collect the rows that are duplicates and give an error with the duplicates before the merge happens. I have two scenarios to cover. The first scenario is duplicates on a single column. The second scenario is duplicates on two columns. Any help on the first scenario would be appreciated.
Scenario 1:
The two tables have the exact same column structure so to keep it simple I will use the following table structure. ( I simply added two tables inside access and run the query to figure out the correct syntax.)
Duplicates based upon one column:
Table1 Table2
ID ID
1 1
2 3
Running the query:
Select ID from Table1
Union ALL
Select ID from Table2
group by ID having count(*) > 1
The result set is always the records from the first select statement. In other words it always returns Id=1 and Id=2. If you change Table1 to Table2 the result set is always from table2. If I change "Union all" to union same results. I tried changing the ID column names as well as change the type to be number instead of auto. Any idea what am I doing wrong?
Scenario 2: I know what the value should be in the second column so it is hard-coded. I added this here to show access appears to work as expected in this scenario but not in scenario 1.
Duplicates based upon two columns:
Table1 Table2
ID Field1 ID Field1
1 abc 1 abc
2 bcd 3 abc
Running the query below works as expected. The row with ID=1 is only returned.
select ID, Field1 from Table1 where Field1 = 'abc'
union all
select ID, Field1 from Table2 where Field1 = 'abc'
group by ID, Field1 having count(*) > 1
The GROUP BY is only being applied to the second table. You need to do the UNION ALL first, and then the GROUP BY and HAVING on a SELECT from the combined results.
Not Access specific, but something like this works:
SELECT id FROM
(
SELECT id FROM a
UNION ALL
SELECT id FROM b
) AS c
GROUP BY id HAVING COUNT(*) > 1
My preferred way to do things like that is to use the build in Query Wizard:
Query Wizard, Find Duplicates Query Wizard
Let Access create the SQL statement for you and then you can modify it and/or move it into code.
I have a simple MYSQL table with about 5 columns or so. The row size of the table changes quite frequently.
One of these columns is named has_error, and is a column that has a value of either 1 or 0.
I want to create a single SQL query that will be the equivalent of the following simple equation:
(Number of rows with has_error = 1/Total number of rows in table) * 100
I can create the individual SQL queries (see below), but not sure how to put it all together.
SELECT COUNT(*) AS total_number_of_rows FROM my_table
SELECT COUNT(*) AS number_of_rows_with_errors FROM My_table WHERE has_error = 1
This is easy because you can just use avg(has_error):
SELECT AVG(has_error) * 100
FROM My_table;
I have a table with four columns to hold anywhere from 1 to 4 userID values. I.e. userid1, userid2, userid3, userid4
I know I can do this:
select * from table where userid=userid1 or userid=userid2 or userid=userid3 or userid=userid4;
Will this also work?
select * from table where userid in (userid1,userid2,userid3,userid4);
I'm wondering if there is a more-efficient method of doing queries like this? Using merged indexes? This table could end up being extremely large so any advice on how I should create indexes would be helpful.
I have a PHP coma separated string of ids like 1,2,3. I have a MySQL table which has id column
Table task_comments:
id
--
1
2
I want to get all the ids in the list which are not in the table. Here i would like to get the 3 as result.
Currently I am building a query like the following in PHP and it is working.
SELECT id FROM (
SELECT 1 id FROM DUAL
UNION ALL
SELECT 2 id FROM DUAL
UNION ALL
SELECT 3 id FROM DUAL
) a WHERE id NOT IN (SELECT id FROM task_comments);
I don't think this is a good way to do this. I want to know if there is a better method to do this, because if the list is big the union list will grow.
Thanks
PS: I can post the PHP code used to make the query also if needed.
PPS: I would like to know if there is better MySQL Query.
Your string separated values in PHP:
$my_ids = "1,2,3";
SQL query in PHP:
$query = "SELECT id FROM task_comments WHERE id IN ($my_ids)";
This will return the id values from database which is 1 or 2 or 3.
Then you can simply compare it.
What you do is already the way to do it. There is no other way to create sets to reason over than the (pretty ugly) union construct. You can leave of the "from dual"s and replace the union alls with plain unions to make it shorter - although with a very large list union all might be the more performant solution as it does not sort for duplicate deletion.
SELECT id FROM (
SELECT 1 id
UNION
SELECT 2 id
UNION
SELECT 3 id
) a WHERE id NOT IN (SELECT id FROM tasklist);
You might also want to have a look at temporary tables. That way you could create the set you need in a more natural way without hitting the limits of the large SQL involving unions.
CREATE TEMPORARY TABLE temp_table (id int);
INSERT INTO temp_table VALUES((1),(2),(3)); -- or just repeat for as many values as you might have from your app (batch insert?)
SELECT id FROM temp_table
WHERE id NOT IN (SELECT id FROM tasklist);
See more on temporary tables here.
You can do it like that: select your ids:
SELECT id FROM task_comments WHERE id IN (1,2,3)
(here (1,2,3) is built from your array data - for example, via implode() function)
Then, in a cycle, fetch your ids into an array and then use array_diff() to find absent values.
May be you should first save all the distinct id's from the table that are present in your string of id's -
SELECT DISTINCT id FROM task_comments WHERE id IN (1,2,3..)
and then compare the two.
Tried to find the answer, but still couldn't.. The table is as follows:
id, keyword, value
1 display 15.6
1 harddrive 320
1 ram 3
So what i need is something like this.. Select an id from this table where (keyword="display" and value="15.6") AND (keyword="harddrive" and value="320")
There's also a possibility that there will be 3 or 4 such keyword conditions which should result into returning one id (one row)
It seems there's something to deal with UNION but i didn't use it before so i can't figure it out
Thanks in advance
This is a relational division problem. Something like the following should do it.
SELECT id
FROM your_table
WHERE
(keyword="display" and value="15.6") OR (keyword="harddrive" and value="320")
GROUP BY id
HAVING COUNT(*) = 2
I'm assuming that your table has appropriate constraints such that it is impossible for there to be a completely duplicated row. (e.g. there is a PK on id, keyword)
SELECT DISTINCT id FROM table
WHERE
(keyword="display" and value=15.6) OR (keyword="harddrive" and value=320)