I have this MYSQL table named people with the columns: id|firstname|lastname|birthdate|phone.
I am quite new to MYSQL and I'm trying to UNION several SELECTs so that the result will look in the following way:
only the first 20 results must be shown
the first SELECT criteria is by the combination firstname+lastname+birthdate: WHERE (birthdate="1980-01-01") AND ((firstname LIKE "%john%") AND (lastname LIKE "%smith%"))
the second SELECT criteria is by the combination firstname+lastname: WHERE (firstname LIKE "%john%") AND (lastname LIKE "%smith%")
the third SELECT criteria is by phone: WHERE phone="0123456"
the output result must in fact have 3 columns: order|id|type; where "order" and "type" are alias columns
the exported ids must be unique: if the same id results from all the 3 SELECTs (or from more than one SELECT), then it must appear only once in the output table
the column "order" must have the value 1 for the results of the first SELECT, 2 for the 2nd SELECT and 3 for the last SELECT
if the same id value results from more than one SELECT, then its row must have the highest order value; where the highest order posible is 1, from the first SELECT
the alias column "type" must work like this: if an id results from the 1st SELECT, it's type value is "~firstname+lastname+birthdate~"; if an id results from the 2nd SELECT, it's type value is "~firstname+lastname~"; and finally if an id results from the 3rd SELECT, it's type value is "~phone~"
if the same id value results from more than one SELECT, the value on the "type" alias column must be a concatention between the SELECTs where that id was found (for example, if the same id resulted in all 3 SELECT queries then the value on the "type" column would be "~firstname+lastname+birthdate~~firstname+lastname~~phone~")
Is it possible to achieve such an output?
Here's something using CASE statements. I think you'll get into a mess with union statements, because of your order type statement. Hopefully I've understood what you're after - it's much easier if you post sample data! Anyway, even if this doesn't do exactly what you want, you get the idea....
[EDIT] I don't think you need the distinct, but I don't think it hurts, either...
SELECT DISTINCT
CASE WHEN birthdate='1980-01-01'
AND firstname LIKE '%john%' AND lastname LIKE '%smith%'
THEN 1
WHEN firstname LIKE '%john%' AND lastname LIKE '%smith%'
THEN 2
WHEN phone='0123456'
THEN 3
END AS outputorder, -- avoid confusion of using an SQL keyword as a column name,
id,
CONCAT(
CASE
WHEN birthdate='1980-01-01'
AND firstname LIKE '%john%' AND lastname LIKE '%smith%'
THEN CONCAT('~',firstname,'+',lastname,'+','~')
END ,
CASE WHEN firstname LIKE '%john%' AND lastname LIKE '%smith%'
THEN CONCAT('~',firstname,'+',lastname,'~')
END ,
CASE WHEN phone='0123456'
THEN CONCAT('~',phone,'~')
END
) -- end the concat
AS outputtype
FROM
mytable
WHERE
( birthdate='1980-01-01'
AND firstname LIKE '%john%' AND lastname LIKE '%smith%')
OR
(firstname LIKE '%john%' AND lastname LIKE '%smith%')
OR
phone='0123456'
ORDER by 1,2 LIMIT 20
In the end I did something like this and it worked just fine:
SELECT MIN(`ord`) AS `order` , `id` , GROUP_CONCAT(`spec`) as `type` FROM (
SELECT "1" AS `ord` , `id` , "~firstname+lastname+birthdate~" AS `spec` FROM `people` WHERE (`birthdate` = "1986-04-02") AND (`lastname` LIKE "%smith%") AND (`firstname` LIKE "%john%")
UNION
SELECT "2" AS `ord` , `id` , "~firstname+lastname~" AS `spec` FROM `people` WHERE (`lastname` LIKE "%smith%") AND (`firstname` LIKE "%john%")
UNION
SELECT "3" AS `ord` , `id` , "~phone~" AS `spec` FROM `people` WHERE (`phone`="0123456")
) final
GROUP BY final.`id`
ORDER BY `order` ASC
LIMIT 20
Thanks to mlinth for the alternative though...
Related
I am quite the novice at MYSQL and would appreciate any pointers - the goal here would be to automate a categorical field using GROUP_CONCAT in a certain way, and then summarize certain patterns in the GROUP_CONCAT field in a new_column. Furthermore, is it possible to add the new_column to the original table in one query? Below is what I've tried and errors to an unknown column "Codes" if this assists:
SELECT
`ID`,
`Code`,
GROUP_CONCAT(DISTINCT `Code` ORDER BY `Code` ASC SEPARATOR ", ") AS `Codes`,
IF(`Codes` LIKE '123%', 'Description1',
IF(`Codes` = '123, R321', 'Description2',
"Logic Needed"))
FROM Table1
GROUP BY `ID`
Instead of nested if statements, I would like to have a CASE statement as a substitute. Reason being is that I already have around 1000 lines of logical already written as "If [column] = "?" Then "?" else if" etc. I feel like using CASE would be an easier transition with the logic. Maybe something like:
SELECT
`ID`,
`Code`,
GROUP_CONCAT(DISTINCT `Code` ORDER BY `Code` ASC SEPARATOR ", ") AS `Codes`,
CASE
WHEN `Codes` LIKE '123%' THEN 'Description1'
WHEN `Codes` = '123, R321' THEN 'Description2'
ELSE "Logic Needed"
END
FROM Table1
GROUP BY `ID`
Table Example:
ID,Code
1,R321
1,123
2,1234
3,1231
4,123
4,R321
Completed Table:
ID,Codes,New_Column
1,"123, R321",Description2
2,1234,Description1
3,1231,Description1
4,"123, R321",Description2
How then can I add back the summarized data to the original table?
Final Table:
ID,Code,New_Column
1,R321,Description2
1,123,Description2
2,1234,Description1
3,1231,Description1
4,123,Description2
4,R321,Description2
Thanks.
You can't refer to a column alias in the same query. You need to do the GROUP_CONCAT() in a subquery, then the main query can refer to Codes to summarize it.
It also doesn't make sense to select Code, since there isn't a single Code value in the group.
SELECT ID, Codes,
CASE
WHEN `Codes` = '123, R321' THEN 'Description2'
WHEN `Codes` LIKE '123%' THEN 'Description1'
ELSE "Logic Needed"
END AS New_Column
FROM (
SELECT
`ID`,
GROUP_CONCAT(DISTINCT `Code` ORDER BY `Code` ASC SEPARATOR ", ") AS `Codes`
FROM Table1
GROUP BY ID
) AS x
As mentioned in a comment, the WHEN clauses are tested in order, so you need to put the more specific cases first. You might want to use FIND_IN_SET() rather than LIKE, since 123% will match 1234, not just 123, something
I'm trying to create a query that count (or at least retrieve) distincts occurrences of a substring in a column.
I have one column that is like this:
elem1=value1|elem2=value2|elem3=value3
I want to retrieve distincts values of elem2 and the number of ocurrences.
SELECT
substring(
column , LOCATE( 'elem2=' , column ) + $1 , $2
) AS a ,
COUNT(*) b ,
FROM
column ORDER BY a;
Thanks
Here's one way to achieve the specified result.
SELECT COUNT(DISTINCT SUBSTRING_INDEX(SUBSTRING_INDEX(t.col,'elem2=',-1),'|',1))
FROM t
WHERE t.col LIKE '%elem2=%'
Apparently, I misread the question (the query above returns a count of distinct values. Or, I just lost track of the specified result, while I was working on the tedious string parsing.
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(t.col,'elem2=',-1),'|',1) AS a
, COUNT(*) AS b
FROM t
WHERE t.col LIKE '%elem2=%'
GROUP BY SUBSTRING_INDEX(SUBSTRING_INDEX(t.col,'elem2=',-1),'|',1)
ORDER BY SUBSTRING_INDEX(SUBSTRING_INDEX(t.col,'elem2=',-1),'|',1)
NOTE:
Note that SQL wasn't really designed for parsing values out of strings.
The normative relational pattern for this type of data would to create a table, with columns named elem1, elem2, elem3, and to store each separate value in a column.
For example:
CREATE TABLE t
( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY
, elem1 VARCHAR(80)
, elem2 VARCHAR(80)
, elem3 VARCHAR(80)
);
INSERT INTO t (elem1, elem2, elem3) VALUES ('value1', 'value2', 'value3');
To get a count of distinct values in elem2 column, we'd do something like this.
SELECT COUNT(DISTINCT elem2)
FROM t
To get the distinct values of elem2 along with the count of occurrences
SELECT elem2 AS a
, COUNT(*) AS b
FROM t
GROUP BY elem2
ORDER BY elem2
That's essentially the same as the query at the beginning of my answer; the first query just has to do the parsing the 'elem2=value2' out of the string.
I am trying to search two columns where value is alike and only display the data of the column that has the value not the other column, both columns can not contain the same value.
My code
SELECT CONCAT(`fname`,`lname`)as name ,date
FROM `table` WHERE id='1' AND CONCAT(`fname`,`lname`) LIKE '%james%'
ORDER BY date ASC LIMIT 0,1
The current query outputs both fname and last name value where it finds the %like% i just want it to output only the column where the %like% is found.
Try this:
SELECT
CASE
WHEN fname LIKE '%james%'
THEN fname
ELSE lname
END
AS name
FROM `table`
WHERE id='1' AND CONCAT(`fname`,`lname`) LIKE '%james%'
ORDER BY date ASC LIMIT 0,1
select concat(if(fname, fname, ""), if(lname, lname, "")) as name, date ...
I am trying to write a select statement that uses several keywords to search by. For example
SELECT id FROM my_mod mm WHERE (mm.name LIKE '%joe%' OR mm.name LIKE '%jim%');
What I would like to do is in the return data have a extra column that counts the number of times that row matches one of the like statements.
So for the one above if there is a name jimjoe it would have a count of 2 or if the name is jim it would have a count of 1. Does anyone know of a way to do this?
I should also mention that I can't use temp tables.
SELECT id,
CASE
WHEN mm.name LIKE '%joe%'
AND mm.name LIKE '%jim%' THEN 2
ELSE 1
end AS cnt
FROM my_mod mm
WHERE mm.name LIKE '%joe%'
OR mm.name LIKE '%jim%'
Try this query -
SELECT
COUNT(IF(name LIKE '%joe%', 1, NULL)) joe_count,
COUNT(IF(name LIKE '%jim%', 1, NULL)) jim_count
FROM
my_mod
WHERE
name LIKE '%joe%' OR name LIKE '%jim%'
Try this
select t.id,count(*) FROM
((select id from my_mod where name like '%jim%')
union all
(select id from my_mod where name like '%joe%')) t group by t.
I check here how it works
i am trying to sort mysql data with alphabeticaly like
A | B | C | D
when i click on B this query runs
select name from user order by 'b'
but result showing all records starting with a or c or d i want to show records only starting with b
thanks for help
i want to show records only starting with b
select name from user where name LIKE 'b%';
i am trying to sort MySQL data alphabeticaly
select name from user ORDER BY name;
i am trying to sort MySQL data in reverse alphabetic order
select name from user ORDER BY name desc;
but result showing all records
starting with a or c or d i want to
show records only starting with b
You should use WHERE in that case:
select name from user where name = 'b' order by name
If you want to allow regex, you can use the LIKE operator there too if you want. Example:
select name from user where name like 'b%' order by name
That will select records starting with b. Following query on the other hand will select all rows where b is found anywhere in the column:
select name from user where name like '%b%' order by name
You can use:
SELECT name FROM user WHERE name like 'b%' ORDER BY name
If you want to restrict the rows that are returned by a query, you need to use a WHERE clause, rather than an ORDER BY clause. Try
select name from user where name like 'b%'
You do not need to user where clause while ordering the data alphabetically.
here is my code
SELECT * FROM tbl_name ORDER BY field_name
that's it.
It return the data in alphabetical order ie; From A to Z.
:)
I had the same challenge, but after little research I came up with this and it gave me what I wanted, and I was able to overcome that path.
SELECT * from TABLE ORDER BY name
Wildcard Characters are used with like clause to sort records.
If we want to search a string which is starts with B then code is like the following:
select * from tablename where colname like 'B%' order by columnname ;
If we want to search a string which is ends with B then code is like the following:
select * from tablename where colname like '%B' order by columnname ;
If we want to search a string which is contains B then code is like the following:
select * from tablename where colname like '%B%' order by columnname ;
If we want to search a string in which second character is B then code is like the following:
select * from tablename where colname like '_B%' order by columnname ;
If we want to search a string in which third character is B then code is like the following:
select * from tablename where colname like '__B%' order by columnname ;
Note : one underscore for one character.
I try to sort data with query it working fine for me please try this:
select name from user order by name asc
Also try below query for search record by alphabetically
SELECT name FROM `user` WHERE `name` LIKE 'b%'
MySQL solution:
select Name from Employee order by Name ;
Order by will order the names from a to z.