MySQL Select when case - mysql

i have those tables and i want to check the same attribute at the same time:
Person
id---name
1----Paul
2----Tom
3----Jim
Age
id---wert------personId
1----28--------1
2----25--------1
3----30--------3
i want to do something like this.
select * from Person p, Age where personId = p.id and CASE WHEN
name = 'Paul' THEN Age > 28 WHEN name = 'Tom' THEN Age <....
How it is possible? With a CASE THEN in the WHERE clause? Please don't think about the structure of the table but only about the principle.
Any Ideas?
Thank

What you're trying to do is possible like so
select
*
from
Person p, Age
where personId = p.id
and CASE
WHEN name = 'Paul' THEN Age > 28
WHEN name = 'Tom' THEN Age <....
WHEN expr then expr that evals to bool
END

CASE WHEN THEN I believe need to be part of an expression, not an expression themselves. It's common use case is in the select, however you can use it in the where.
In a select this would be:
select
case name
when 'paul' then 28
when 'jim' then 30
end
from X
To use it within an where you would do this:
select * from X where age = case name when 'jim' then 28 else 30 end
Depending on what you are attempting to achieve, you may want to consider OR statements instead of case in your where clause.

Related

mysql regexp for all column with same data

i have a table like this.
id name father_name age
1 raja first 12
2 second first 13
When i execute a below query.
SELECT * FROM class WHERE name REGEXP 'first|12'
OR father_name REGEXP 'first|12'
OR age REGEXP 'first|12'
I getting below as a results.
id name father_name age
1 raja first 12
2 second first 13
But I want below as a result.
id name father_name age
1 raja first 12
If I change name with or condition. I can achieve.But
As same time the user given raja|12 means
SELECT * FROM class WHERE name REGEXP 'raja|12'
OR father_name REGEXP 'raja|12'
OR age REGEXP 'raja|12'
I want the result like this.
id name father_name age
1 raja first 12
Because i dont know which one will get from user name or father_name or age or all the three. So if i get all the three there is no problem. But when i get a singl or doble values so i need to search regarding that.
Is there any possibility to get those results?
You seem to want and instead of or, but this is complicated by the fact that you don't seem to care about name. I'm tempted to say:
SELECT *
FROM class
WHERE father_name REGEXP 'first|12' AND
age REGEXP 'first|12';
I'm not sure what name is doing in the WHERE clause.
EDIT:
It occurs to me that you want the best matching row. If so:
SELECT *
FROM class
WHERE name REGEXP 'first|12' OR
father_name REGEXP 'first|12' OR
age REGEXP 'first|12'
ORDER BY ((name REGEXP 'first|12') + (father_name REGEXP 'first|12') + (age REGEXP 'first|12')) DESC
LIMIT 1;
Please be aware that REGEXP 'xx|yy' means this matches xx OR yy so your result is correct for that query.
To get the result you want, you will have to clarify what you want to achieve. I assume you want the follwing: select all rows where the father is first AND age is 12
You can achieve this by using:
SELECT * FROM mytable WHERE father_name like 'first' AND age = 12;
You can try this solution here: Relevant SqlFiddle.
Edit1: Possible alternative soultion after more comments by OP:
SELECT * FROM mytable WHERE
father_name IN ('first', '12') AND age IN ('first', '12')
OR
father_name IN ('first', '12') AND name IN ('first', '12')
OR
name IN ('first', '12') AND age IN ('first', '12');
You can try this solution here: Relevant SqlFiddle.

SQL Query handle multiple WHERE

I intend to generate report through web interface.
My page content two field:
----------------------
Gender: Male Female (radio button)
Age: 10 to 20 (Select list)
------------------
How can I write query, they handle both situation, if user provide only "Gender" base WHERE clause or required gender or Age base WHERE clause.
I am want to write single query handle both situation.
Please help me
Regards,
Use and:
select *
from yourTable
where gender = 'Male'
and age between 10 and 20
If it is unsure whether a user enters a value, try or and a null check. You can do the same for gender:
select *
from yourTable
where gender = 'Male'
and (age is null or age between 10 and 20)
Your base query should be something like
SELECT *
FROM Customer
WHERE 1=1
And you should add clauses (" AND gender = something", " AND age between something and something") based on the parameters provided by user.
If the user does not select any parameters, the base query should work fine. If the user provides a parameter or both, the query becomes something like:
SELECT *
FROM Customer
WHERE 1=1
AND gender = "male"

Select statement gives different set of records

SELECT Count(*)
FROM stu_empl_pers
WHERE site_id = 'DEXLER';
returns 22 records.
but
SELECT Count(*)
FROM stu_empl_pers a
WHERE a.status = 'A'
OR a.faculty = 1
OR a.staff = 1
AND a.site_id = 'DEXLER';
returns 691 records.It considers different site_id also.Can anybody elaborate on this?
WHERE a.status='A' or a.faculty=1 OR a.staff=1 AND a.site_Id = 'DEXLER';
(true/false or true/false or (true/false and true/false))
maybe this will be more easier to see what your WHERE statement mean
if one of ORs (except the one with AND) become true the record will be added to the result
think AND like multiplication operand in math it has priority over OR which can be considered like sum operand in math
2*2-1 = 3 Not 2
I need status=A and site_id='dexler'as mandatory
then, could you try this?
Select count(*) from stu_empl_pers a
WHERE (a.faculty=1 OR a.staff=1)
AND a.status='A' AND a.site_Id = 'DEXLER';
That's because the filter conditions are different. The OR will return all records abiding to both filter condition.
Maybe what you're looking for in the second query is;
SELECT Count(*)
FROM stu_empl_pers a
WHERE ( a.status = 'A'
OR a.faculty = 1
OR a.staff = 1 )
AND a.site_id = 'DEXLER'; <-- missing brackets
Where you're adding a second level filter (a.status='A' OR a.faculty=1 OR a.staff=1) to the first query.

Select multiple sums with MySQL query and display them in separate columns

Let's say I have a hypothetical table like so that records when some player in some game scores a point:
name points
------------
bob 10
mike 03
mike 04
bob 06
How would I get the sum of each player's scores and display them side by side in one query?
Total Points Table
bob mike
16 07
My (pseudo)-query is:
SELECT sum(points) as "Bob" WHERE name="bob",
sum(points) as "Mike" WHERE name="mike"
FROM score_table
You can pivot your data 'manually':
SELECT SUM(CASE WHEN name='bob' THEN points END) as bob,
SUM(CASE WHEN name='mike' THEN points END) as mike
FROM score_table
but this will not work if the list of your players is dynamic.
In pure sql:
SELECT
sum( (name = 'bob') * points) as Bob,
sum( (name = 'mike') * points) as Mike,
-- etc
FROM score_table;
This neat solution works because of mysql's booleans evaluating as 1 for true and 0 for false, allowing you to multiply truth of a test with a numeric column. I've used it lots of times for "pivots" and I like the brevity.
Are the player names all known up front? If so, you can do:
SELECT SUM(CASE WHEN name = 'bob' THEN points ELSE 0 END) AS bob,
SUM(CASE WHEN name = 'mike' THEN points ELSE 0 END) AS mike,
... so on for each player ...
FROM score_table
If you don't, you still might be able to use the same method, but you'd probably have to build the query dynamically. Basically, you'd SELECT DISTINCT name ..., then use that result set to build each of the CASE statements, then execute the result SQL.
This is called pivoting the table:
SELECT SUM(IF(name = "Bob", points, 0)) AS points_bob,
SUM(IF(name = "Mike", points, 0)) AS points_mike
FROM score_table
SELECT sum(points), name
FROM `table`
GROUP BY name
Or for the pivot
SELECT sum(if(name = 'mike',points,0)),
sum(if(name = 'bob',points,0))
FROM `table
you can use pivot function also for the same thing .. even by performance vise it is better option to use pivot for pivoting... (i am talking about oracle database)..
you can use following query for this as well..
-- (if you have only these two column in you table then it will be good to see output else for other additional column you will get null values)
select * from game_scores
pivot (sum(points) for name in ('BOB' BOB, 'mike' MIKE));
in this query you will get data very fast and you have to add or remove player name only one place
:)
if you have more then these two column in your table then you can use following query
WITH pivot_data AS (
SELECT points,name
FROM game_scores
)
SELECT *
FROM pivot_data
pivot (sum(points) for name in ('BOB' BOB, 'mike' MIKE));

disperse relational structure of MySQL table

I have a table that consists of
id (auto_increment)
number int (can contain values from 10 to 12)
myvalue (varchar)
What I want to do is disperse the relational structure of this table for report purpose. I.e , I´d like to have something like:
id (auto_increment)
number10 (containing myvalue WHERE number=10)
number11 (containing myvalue WHERE number=11)
number12 (containing myvalue WHERE number=12)
I know that I can get the respective results by
SELECT myvalue FROM mytable WHERE number = 10;
but I haven´t figured out how to write these three SELECT statements into one single table or view.
thx for any help in advance!
Something like this maybe?:
SELECT
id,
IF(number=10, myvalue, NULL) AS number10,
IF(number=11, myvalue, NULL) AS number11,
IF(number=12, myvalue, NULL) AS number12
FROM mytable
This might do what you need. You've not explained it very well though so it might not!
SELECT user,
MIN(CASE WHEN number = 10 then myvalue end) AS number10,
MIN(CASE WHEN number = 11 then myvalue end) AS number11,
MIN(CASE WHEN number = 12 then myvalue end) AS number12
FROM table
WHERE number IN (10,11,12)
GROUP BY user
I don't get the "id number10 number11 number12" stuff, but if you want to select the rows with the number field matching a set of values, you can just do:
SELECT * FROM mytable WHERE number IN (10, 11, 12);
Or, alternatively, you can select a number range:
SELECT * FROM mytable WHERE number >= 10 AND number <= 12;
Edit 2:
Vin-G's got it. I was way off.