Find rows in which id can be in one of several columns - mysql

Is there a more elegant SQL query for selecting rows in which ID can be in col1 or col2 or col3, etc. without a long condition containing plenty of OR operators ?
I'd like to produce the same result as the following query:
SELECT *
FROM tab
WHERE (col1 = _x_ OR col2 = _x_ OR col3 = _x_);

You can use something like :
select * from tab where 'x' in (col1, col2, col3...)

Related

Mysql select query can't able to search symbolic string

For example if I want to search below.
> lav'ro (I can't search it by "lav'r" because of ' in the string)
> am[op]st (I can't search it by "am[o" because of [ in the string)
My question is how can I use select query so I will help me to bring output?
Below are my SELECT query.
SELECT * FROM TableName
WHERE (Col1 LIKE '%$value%' OR Col2 LIKE '%$value%')
ORDER BY
CASE WHEN (Col1 LIKE '$value' AND Col2 LIKE '$value') THEN 1
WHEN Col1 LIKE '$value' THEN 2
WHEN Col2 LIKE '$value' THEN 3
WHEN Col1 LIKE '$value%' THEN 4
WHEN Col2 LIKE '$value%' THEN 5
WHEN Col1 LIKE '%$value' THEN 6
WHEN Col2 LIKE '%$value' THEN 7
WHEN Col1 LIKE '%$value%' THEN 8
WHEN Col2 LIKE '%$value%' THEN 9
ELSE 10
END asc,
length(Col1 or Col2) limit 15
Here "$value" dynamic word for search.
It's working well In normal search, problem with symbolic search.
You have to include \ before the single quote to make it work
SELECT * FROM `table` WHERE `column` LIKE 'lav\'ro'
For the 2nd issue try % to append before or after or both
SELECT * FROM `table` WHERE `column` LIKE '%am[o%'
You don't have to use like. You can just use instr() or =:
where instr(col1, ?) > 0
Use like and regular expressions when you need them for their pattern matching capabilities.
And -- for the record -- there is no problem searching for single quotes in a string. The only problem is expressing the string. To do this, double up on the single quote:
where col1 like concat(?, '%')
works when you pass a parameter with a single quote. This also works:
where col1 like 'lav''r%'

MYSQL - Create View to query two like tables

I have to like tables Order_Items and Order_Items_Archived which both tables are InnoDB. I would like to create a query that I can pull all the Items from both orders. I am pretty sure I would do this with a VIEW but I cant seem to find reference to just select all records that have the exact same column names and column types.
Example:
select sum(OrderItems_Amount)
from Order_Items_View
where OrderItems_OrderDate = '2017-10-01';
Sounds like you're looking for the union all operator:
CREATE OR REPLACE VIEW order_items_view AS
SELECT * FROM order_items
UNION ALL
SELECT * FROM order_items_archived
You would use a union all query. I would be inclined to add the source. List the columns that you want:
select col1, col2, col3, . . . , 0 as is_archive
from order_items
union all
selecct col1, col2, col3, . . ., 1
from order_items_archive;
You can put a create view statement before the query to turn it into a view.

How to get all data from Tables in SQL with similar name in R

i am new to R and i want to merge multiple Tables from my SQL DB with R.
The problem is not to merge them, but to get the query. I have a lot of tables with similar name(just numbers at the end are different) in the DB.
Now i want the data in these tables to work with them in R. I already tried to import these table names from a .txt document and this works. But i canĀ“t use the function dbGetQuery(connection, "SELECT * FROM...")
right with with method because it allows only the real table name and no variable with multiple names.
Over that i tried
dbGetQuery(connection,
"SELECT * FROM INFORMATION_SCHEMA.tables WHERE TABLE_NAME LIKE '..._%'")
but this gives just table names and not the data in there.
I hope anyone can understand my problem.
Just concatenate the SQL query using paste or sprintf function:
dbGetQuery(connection, sprintf("select * from %s", table_name))
By executing this for each table_name obtained from the INFORMATION_SCHEMA.tables query, you will have tables' data in R.
Import all tables to list and merge in R. (Included LIMIT 100 for test purposes)
tables <- dbGetQuery(con, {"
SELECT concat(TABLE_SCHEMA,'.',TABLE_NAME) tab
FROM INFORMATION_SCHEMA.tables
WHERE TABLE_NAME LIKE 'pattern%'"})$tab
data <-
lapply(tables, function(table){
dbGetQuery(con, sprintf({"
SELECT *
FROM %s
LIMIT 100
"}, table)
)
})
library(magrittr);library(dplyr)
data %<>% bind_rows()
Or if one wants to keep it in MySQL, and is sure that tables have same structure, function below returns query which union all tables matching pattern:
union_all_mysql <- function(pattern){
tables <- dbGetQuery(con, sprintf({"
SELECT concat(TABLE_SCHEMA,'.',TABLE_NAME) tab
FROM INFORMATION_SCHEMA.tables
WHERE TABLE_NAME LIKE '%s'"}, pattern)
)$tab
query <-
lapply(tables, function(table)
sprintf("select * from %s", table) ) %>%
unlist
paste(query,collapse=" union ")
}
union_all_mysql("users_%")
I wouldn't do this in R, I would do it in Workbench directly. First create a new table to hold the merged results:
CREATE TABLE AllData (
id INT NOT NULL PRIMARY KEY,
col1 varchar(55), -- replace with your actual column types
col2 int,
...
)
Then just do the following INSERT INTO ... SELECT:
INSERT INTO AllData (col1, col2, col3, ..., colN)
SELECT col1, col2, col3, ..., colN
FROM table1
UNION ALL
SELECT col1, col2, col3, ..., colN
FROM table2
UNION ALL
...
SELECT col1, col2, col3, ..., colN
FROM tableM
The above assumes M tables each having the same N columns, but you will have to fill in the blanks yourself.

sql query using LIKE or MATCH

I have a table of 13 columns , out of those i have 5 columns that contains let say string data or VARCHAR data.
Now i have a string let say "abc".
I want to write a sql query to get all the rows that have this "abc" string in those 5 columns. "abc" can be the data of the column of part of the data of the column.
I used LIKE function
SELECT * FROM table WHERE col1 OR col2 OR col3 OR col4 OR col5 LIKE '%abc%';
but it didnt worked n got back all the rows.
I dont know how use MATCH function either, I m nt good in sql. so can anyone help.
You can specify condition multiple times:
SELECT *
FROM table
WHERE col1 LIKE '%abc%'
OR col2 LIKE '%abc%'
OR col3 LIKE '%abc%'
OR col4 LIKE '%abc%'
OR col5 LIKE '%abc%';
This will be really slow because you have multiple OR and non-SARGable condition.
Alternatively:
SELECT *
FROM table
WHERE CONCAT_WS('^', col1,col2,col3,col4,col5) LIKE '%abc%';
Using MATCH (preferred solution that utilizes full-text index):
SELECT *
FROM table
WHERE MATCH(col1, col2,col3,col4, col5) AGAINST ('abc');
SqlFiddleDemo
Keep in mind that to use MATCH you need to create index first:
ALTER TABLE tab ADD FULLTEXT ft_index_name (col1,col2,col3,col4,col5);

MySQL - selecting rows with some values being null

I have the values of 'foo', 'bar' and 'buz'. I'd like to select rows 1 and 3 from the following table:
+----+------+------+------+
| Id | Col1 | Col2 | Col3 |
+----+------+------+------+
| 1 | foo | | |
| 2 | foo | bar | buz |
| 3 | | bar | buz |
+----+------+------+------+
What would be the optimal MySQL query for that considering the following:
empty spaces are null
I have n columns where 4 < n < 20
there will be couple hundred rows
I will be selecting particular combinations of columns in a row where only provided values can be set and the rest needs to be null. E.g.: I need a query of this kind
SELECT * FROM my_table WHERE Col1 = foo OR (Col2 = bar AND Col3 = buz);
that'll return only rows 1 and 3.
In other words I'd like to have a query that returns rows only with certain combinations of values, not the rows where coln = 'some_val' and we dont' care about the others.
The reason for this is that I'd like to have 5 combinations in 1 query and I'd like to avoid writing (...) coln <> NULL(...) everywhere.
I'd appreciate your suggestions.
You would use where clause. To find the three values:
where 'foo' in (col1, col2, col3, . . . ) or
'bar' in (col1, col2, col3, . . . ) or
'buz' in (col1, col2, col3, . . . )
Limiting the results to those three values is more difficult. You need to do a comparison on each column:
where ( (col1 in ('foo', 'bar', 'buz') or col1 is null) or
(col2 in ('foo', 'bar', 'buz') or col2 is null) or
. . .
)
You can use a spreadsheet to generate the code, if you don't want to type it all in.
Another alternative would be the following kludge:
where replace(replace(replace(concat_ws('', col1, col2, col3, . . . ),
'foo', ''
), 'bar', ''
), 'buz', ''
) = ''
This concatenates the values together and then removes the ones you care about. If everything is removed, then the row matches.
As a note: this problem suggests that you have a poor data structure. You are storing things in columns that should be in rows.
I would like the db to assume, that for every field not provided in a query it needs to be NULL for the whole row to be returned. Even if provided values match.
In that case, the trivial solution would be:
SELECT * FROM my_table WHERE
(Col1 = 'foo' AND Col2 IS NULL AND Col3 IS NULL) OR
(Col1 IS NULL AND Col2 = 'bar' AND Col3 = 'buz') OR
/* ... */
In many cases, this can be a perfectly good solution. However, it can sometimes suffer suboptimal performance due to MySQL's poor index use for OR queries. In particular, if you have a combined index on all the columns, and want to make full use of it, it can be better to rewrite the query to use UNION (or UNION ALL) instead of OR:
SELECT * FROM my_table WHERE
(Col1 = 'foo' AND Col2 IS NULL AND Col3 IS NULL) UNION ALL
SELECT * FROM my_table WHERE
(Col1 IS NULL AND Col2 = 'bar' AND Col3 = 'buz') UNION ALL
/* ... */
See this SQLFiddle for a demonstration of the two techniques, and compare the execution plans (the execution times are rather meaningless with such a small table; you'd need many more rows to see any systematic difference). Looking at the KEY_LEN and REF columns, you can see that, for the OR query, MySQL ends up using the index only for Col1, whereas with UNION ALL, it can use the whole index.