MySQL: How to SELECT FROM a custom set - mysql

I have a given list of patient IDs which I want to interact in, something like this:
SELECT * FROM (LIST OF IDs) WHERE ....
is it possible to have something similar to this using mysql?

it is feasible using IN in WHERE section
SELECT * FROM <table> WHERE <field> IN (<your list of ids comma separated>)
Note that this is valid up to 10 ids. With more the performance of the query will definitively decline and there are different approaches (temporary tables to join). But in that case I'd review your database schema to see if this is the correct approach

I would definitely recommend to use a subquery in WHERE id IN (...), just like this:
SELECT *
FROM table1
WHERE id IN (SELECT id
FROM table1
WHERE conditions... )
With this, you can add more conditions in both WHERE's and performance will be fine.

Related

Is SELECT * clear enough to specify which query we are referring to?

I am new to mySQL.
I am following Mosh's tutorial to familiarize myself to SQL.
Here's my question for the following code.
SELECT *
FROM order_items
WHERE order_id = 6 AND unit_price*quantity > 30
When I looked up about SELECT *, it says: * means to return all all columns of the queried tables. Then I think SELECT * means that it grabs all tables from all schema.
My question is: Isn't it a bit inefficient and confusing to return all column provided my understanding is right? If the database become bigger and bigger, it will consume unnecessary effort to look up the keyword, so I think SELECT should specify what table it is referring to. Thanks for reading! 🥰
SELECT * does not fetch all tables from all schema. It only fetches the columns from the table you reference in your FROM clause. It only fetches the rows that match your WHERE clause.
The mistake is understandable given this statement in the MySQL documentation:
A select list consisting only of a single unqualified * can be used as shorthand to select all columns from all tables:
SELECT * FROM t1 INNER JOIN t2 ...
What they mean by "all tables" is only all tables referenced in this query. And only those in FROM or JOIN clauses. Not all tables everywhere.

Simulate MySQL records using inline data

This may sound like an odd question, but I'm curious to know if it's possible...
Is there a way to simulate MySQL records using inline data? For instance, if it is possible, I would expect it to work something like this:
SELECT inlinedata.*
FROM (
('Emily' AS name, 26 AS age),
('Paul' AS name, 56 AS age)
) AS inlinedata
ORDER BY age
Unfortunately MySQL does not support the standard values row-constructor for this kind of things, so you need to use a "dummy" select for each row and combine the rows using UNION ALL
SELECT *
FROM (
select 'Emily' AS name, 26 AS age
union all
select 'Paul', 56
) AS inlinedata
ORDER BY age
The UNION ALL serves two purposes
It preserves any duplicate you might have on purpose
It's a (tiny) bit faster than a plain UNION (because it does not check for duplicates)
No, not without making it complicated, but you can create a temporary table and query that instead. Temporary tables are deleted when the current client session terminates.
You can query them and insert data into them just like with other tables. When you create them, you have to use the TEMPORARY keyword, like so:
CREATE TEMPORARY TABLE ...
This way, you can also reuse the data for multiple queries if needed, no data gets stored, and all records that you query have the right structure (whereas the syntax you give in your example would create problems when you spell a column name wrong)...
with cte as (
select '2012-04-04' as student_dob, '%test1%' as student_pat
union all
select '2012-05-04', '%test2%'
union all
select '2012-07-04', '%test3%'
union all
select '2012-05-11', '%test-n%'
)
select *
from students s
inner join cte c
on s.student_dob = c.student_dob and s.student_name like c.student_pat
arguably that's not a lot more readable, but taking a lead from that, you can just store those in a table or go through temporary table, like Roy suggested.
Also it's not great idea to make a group by student id and select also something else like you did in 2nd query.

SELECT statement issue with OR

I am trying to do a filter query by using the next statement:
SELECT * FROM user_jobs,users WHERE user_jobs.job_title LIKE "%some_keyword%" **OR** user_jobs.job_title LIKE "%another_keyword%" AND user.id=user_jobs.userid
Specs: users.id is PK and user_jobs.userid is FK to users.id
I am trying to filter the users to get the ones that have similar values as specified. When I run it I get a very long loop and finally a large list of users that contains duplicates. (e.g. I only have 300 users and the query shows over 3000 results)
What am I doing wrong, please?
Thanks in advance!
AND takes precedence over OR; use parentheses to achieve the desired result.
SELECT * FROM user_jobs, users
WHERE
(user_jobs.job_title LIKE "%some_keyword%"
OR user_jobs.job_title LIKE "%another_keyword%")
AND users.id = user_jobs.userid
You need to use parentheses in that query.
SELECT * FROM user_jobs,users WHERE user.id=user_jobs.userid
AND (user_jobs.job_title LIKE "%some_keyword%"
OR user_jobs.job_title LIKE "%another_keyword%")
First off, the AND operator holds precedence in this case. Isolate your logic like so:
SELECT * FROM user_jobs,users WHERE (user_jobs.job_title LIKE "%some_keyword%" OR user_jobs.job_title LIKE "%another_keyword%") AND user.id=user_jobs.userid
Second of all, don't use SELECT * FROM .... This selects all your data, adding network overhead and taking up more time to transfer it all across the server.
Reference: https://dev.mysql.com/doc/refman/5.0/en/func-op-summary-ref.html
Even though you table contains 300 records it will result around 3000 records because you are selecting columns from both the tables but not giving any join condition in your query , so it will CROSS JOIN both the tables.
and for finding the `JOB_TITLE patter you can use Regular Expressions also as
SELECT * FROM USER_JOBS T1,USERS T2 WHERE REGEXP_LIKE(USER_JOBS.JOB_TITLE ,'SOME_KEYWORD|OTHER_KEYWORD') AND T2.ID=T1.USERID;

SELECT command in mysql

I was wondering if there is a way to do something like selecting all without ... some columns here
something like SELECT */column1,column2 , is there a way to do this ?
I just need to output something like
column1 , column2 ( from another table ) , here all other columns without column1 ( or something to make the select skip the first few columns)
EDIT:
The thing is that i need this to be dynamic , so i cant just select what i don't know. I never know how many columns there will be , i just know the 1st and the 2nd column
EDIT: here is a picture http://oi44.tinypic.com/xgdyiq.jpg
I don't need the second id column , just the last column like i have pointed.
Start building custom views, which are geared aorund saving developers time and encapsulating them from the database schema.
Oh, so select all but certain fields. You have two options.
One is a little slow.. Copy the table, drop the fields you don't want, then SELECT *
The other is to build the field list from a subquery to information_schema or something, then remove occurrences of 'field_i_dont_want' in that list.
SELECT ( SELECT THE TABLES YOU WANT AND CONCAT INTO ONE STRING ) FROM TABLE
If you need to combine records from multiple tables, you need to find a way to relate them together. Primary Keys, Foreign Keys, or anything common among this.
I will try to explain this with a sql similar to your problem.
SELECT table1.id, table2.name, table1.column3, table1.column4
FROM table1
INNER JOIN table2 On table2.commmonfield = table1.commonfield
If you have 'n' columns in your table as in Col1,Col2,Col3....Coln you can select whatever columns you want to select from the table.
SELECT Col1,Col2 FROM YOURTABLE;
You either select all columns (*) or especify the columns you want one by one. There is no way to select 'all but some'.
The SQL language lets you either select a wildcard set of columns or enumerated single columns from a singular table. However you can join a secondary table and get a wildcard there.
SELECT
a.col1,
b.*
FROM
table_a as a
JOIN table_b as b ON (a.col5 = b.col_1)

how to do reverse fulltext search in MySQL?

By default it's like this:
select * from main_table where match(col1,col2) against('search_item');
but what I want to fetch is the reverse,
say,I've restored all the search_item(1000 records,for example),
and I want to see which of them matches a specified row in main_table.
Is that doable?
You could do something like:
SELECT * FROM search_items WHERE (SELECT col1 FROM main_table WHERE ID = XXX) LIKE CONCAT('%',search_item,'%');
That is going to be pretty darn slow if you have a huge dataset to get through.
If speed is an issue, another way to handle this (although admittedly a lot more complicated) is to get all of the data out of the database and build yourself a ternary search tree (also called a trie). Once you get through the overhead of building the trie, matching against input strings is lightning fast compared to brute force methods.
Well I realise this is ten months late but just for the sake of posterity. I think what you're saying is that you want all rows in the search_items table which would not match the query :
select * from main_table where match(col1,col2) against('search_item');
I'm going to assume that your main_table has some unique identifier column which I'll call unqid.
select * from main_table
WHERE
unqid not in (select unqid
from main_table
where match(col1,col2) against('search_item')
)
My first thought was to use a MINUS operator but it turns out MySQL doesn't have one !