I want to compare the value of a column with several list and print something else in each case. Its a list of car brands, like Chevy, Ford and so on. My logic should be like this:
if(mycolumn like carlist1, 'this', '')
if(mycolumn like carlist2, 'that', '')
if(mycolumn like carlist3, 'foobar', '')
mycolumn has a value like Chevy-1234, so it must be a like since the numbers will change. How could I do that in MySQL?
Thanks!
Your best bet is to store the car list as a table, with data like:
Chevy
Ford
and so on.
Then you can do what you want with a join:
select t.*,
max(case when cl.brand = 'Chevy' then 'this' end) as Chevy,
max(case when cl.brand = 'Ford' then 'this' end) as Ford,
. . .
from t left outer join
carlist cl
on left(t.col, length(cl.brand)) = cl.brand
group by t.id
Otherwise, you have to deal with the number:
select (case when left(col, locate('-', col) - 1) = carlist1 then 'this' end),
(case when left(col, locate('-', col) - 1) = carlist2 then 'that' end),
(case when left(col, locate('-', col) - 1) = carlist3 then 'foobar' end)
Try it in mysql like this
SELECT
if(mycolumn like 'carlist1%', 'this', '') as 'Blah1',
if(mycolumn like 'carlist1%', 'that', '') as 'Blah2',
if(mycolumn like 'carlist1%', 'foobar', '') as 'Blah3'
FROM mytable
you may use
SELECT
WHEN mycolumn LIKE 'carlist1%' THEN 'this' END AS Blah1,
WHEN mycolumn LIKE 'carlist1%' THEN 'that' END AS Blah2,
WHEN mycolumn LIKE 'carlist1%' THEN 'foobar' END AS Blah3
FROM mytable
Related
How do I create an entirely new column in SQL while using CASE WHEN, GROUPING_ID(), and ROLLUP() syntax?
So far I have tried:
SELECT Country, ContactTitle, COUNT(ContactTitle) AS Count
,CASE(
WHEN
GROUPING_ID(Legend) = 0 THEN ' '
WHEN
GROUPING_ID(Legend) = 1 THEN 'SUBTOTAL(Country)')
GROUP BY ROLLUP(Country, ContactTitle)
FROM dbo.Customers
SELECT Country, ContactTitle, COUNT(ContactTitle) AS Count,
CASE
WHEN GROUPING_ID(Country,ContactTitle) = 0 THEN ''
WHEN GROUPING_ID(Country,ContactTitle) = 1 THEN CONCAT('Subtotal for ',Country)
END AS Legend
FROM dbo.Customers
GROUP BY ROLLUP(Country, ContactTitle);
A CASE needs an END.
And while testing, you could output the GROUPING_ID or GROUPING to understand what they return.
SELECT Country, ContactTitle, COUNT(*) AS Count,
(CASE
WHEN GROUPING_ID(Country, ContactTitle) = 1
THEN CONCAT('SUBTOTAL(',Country,')')
WHEN GROUPING(Country) = 1
THEN 'TOTAL'
ELSE ' '
END) AS Legend
FROM Customers
GROUP BY Country, ContactTitle WITH ROLLUP;
is there a way of performing a count operation with SQL where the column equals X
and ideally a separate count for when the same column equals Y and again for Z?
SELECT yourcolumn, COUNT(*) AS cnt
FROM yourtable
WHERE yourcolumn IN ('X', 'Y', 'Z')
GROUP BY yourcolumn
Something like this ?
select
sum(case when val = 'x' then 1 else 0 end) as countX
,sum(case when val = 'y' then 1 else 0 end) as countY
,sum(case when val = 'z' then 1 else 0 end) as countZ
from table
I believe the following (shorter) statement should work for MySQL:
SELECT COUNT(val='X'), COUNT(val='Y'), COUNT(val='Z') FROM ...
I would suggest the following:
SELECT YourColumn, COUNT(<Any Column of your table>)
FROM YourTable
GROUP BY YourColumn
I've read a lot of the examples on self join, but they don't seem to cover the case where some fields are not in some rows.
For eg, I have a database with:
testId, testItem, testResult
And the rows:
1,test1,1
1,test2,0
1,test3,1
2,test1,0
2,test4,1
2,test5,1
I would like the output:
testItem,a.testId,b.testId,a.testResult,b.testResult
test1,1,2,1,0
test2,1,NULL,0,NULL
test3,1,NULL,1,NULL
test4,NULL,2,NULL,1
test5,NULL,2,NULL,1
Essentially, I want to compare each testItem (test1->test5) from two different testIds (1 and 2) and compare their testResult values, factoring in testIds that may not have the same test Items.
Given your exact requirement, you can try this:
select testItem
, max(case when testID = 1 then testID else null end) as testID1
, max(case when testID = 2 then testID else null end) as testID2
, max(case when testID = 1 then testResult else null end) as testResult1
, max(case when testID = 2 then testResult else null end) as testResult2
from mytable
where testID in (1,2)
group by testItem
This makes a lot of assumptions about your data, so take it with a grain of salt.
It looks like you want a FULL OUTER JOIN, which is not supported in MySQL. You can emulate this with a UNION of two queries: a LEFT JOIN query and RIGHT JOIN which throws out matching rows.
Something like this will return the specified resultset:
SELECT a.testItem
, a.testId AS `a.testId`
, b.testId AS `b.testId`
, a.testResult AS `a.testResult`
, b.testResult AS `b.testResult`
FROM mytable a
LEFT
JOIN mytable b
ON b.testItem = a.testItem
AND b.testId = 2
WHERE a.testId = 1
AND a.testItem IN ('test1','test2','test3','test4','test5')
UNION ALL
SELECT d.testItem
, c.testId
, d.testId
, c.testResult
, d.testResult
FROM mytable d
LEFT
JOIN mytable c
ON c.testItem = d.testItem
AND c.testId = 1
WHERE d.testId = 2
AND d.testItem IN ('test1','test2','test3','test4','test5')
AND c.testId IS NULL
ORDER
BY 1,2,4
(I included the predicates on testItem IN ('test1' thru 'test5') because you specified that as a requirement; those predicates could be removed if you want all values for testItem included.)
SQLFiddle Demo
select testItem,
group_concat(IFNULL(testId,'null') separator ', ') testIds,
group_concat(IFNULL(testResult, 'null') separator ', ') testResults
from table_name group by testItem;
I am trying to get the count of females and males in the gender field of a table.
Is there a way to get the count of each in one query?
Something like:
select * from table count(where gender = 'm') as total_males, count(where gender = 'f') as total_females;
or will it require two queries?
select count(*) from table where gender = 'm';
select count(*) from table where gender = 'f';
This is basically a PIVOT. MySQL does not have a pivot so you can use an aggregate function with a CASE statement to perform this:
select
sum(case when gender = 'm' then 1 else 0 end) Total_Male,
sum(case when gender = 'f' then 1 else 0 end) Total_Female
from yourtable
See SQL Fiddle with Demo
Or using COUNT:
select
count(case when gender = 'm' then 1 else null end) Total_Male,
count(case when gender = 'f' then 1 else null end) Total_Female
from yourtable;
See SQL Fiddle with Demo
Something like this will work:
SELECT SUM(IF(t.gender='m',1,0)) AS total_males
, SUM(IF(t.gender='f',1,0)) AS total_females
FROM mytable t
The "trick" here is that we are using a conditional test to return either a 0 or a 1 for each row, and then adding up the 0's and 1's. To make this a little more clear, I am using the SUM aggregate function rather than COUNT, although COUNT could be used just as easily, though we'd need to return a NULL in place of the zero.
SELECT COUNT(IF(t.gender='m',1,NULL)) AS total_males
, COUNT(IF(t.gender='f',1,NULL)) AS total_females
FROM mytable t
Consider that the two expressions in the SELECT list of this query:
SELECT COUNT(1)
, SUM(1)
FROM mytable t
Will return the same value.
If you want to avoid the MySQL IF function, this can also be done using the ANSI SQL CASE expression:
SELECT SUM( CASE WHEN t.gender = 'm' THEN 1 ELSE 0 END )) AS total_males
, SUM( CASE WHEN t.gender = 'f' THEN 1 ELSE 0 END )) AS total_females
FROM mytable t
select sum(case when gender='m' then 1 else null end) as total_males, sum(case when gender='f' then 1 else null end) as total_females from ...
Should work just fine!
If your only issue is to avoid two queries, you can always write two queries as subselects of one query.
Select (select 1 from dual) as one, (select 2 from dual) as two from dual
This would work for your scenario, too.
I have a column 'hour'
I have a column 'kind' (it can be 1,2 or 3)
I'd like to do something like:
SELECT count(id), SUM(hour) as totHour, SUM( IF ( kind = 1, 1, 0 ) ) as countKindOne
or
SELECT count(id), SUM(hour) as totHour, COUNT( IF ( kind = 1 ) ) as countKindOne
But mysql tell me I've an error... what's the error!?
Please see this stackoverflow topic: MySQL SUM IF field b = field a
.. I'm not able to reply this ...
You can use a CASE statement:
SELECT count(id),
SUM(hour) as totHour,
SUM(case when kind = 1 then 1 else 0 end) as countKindOne
you want something like:
SELECT count(id), SUM(hour) as totHour, SUM(kind=1) as countKindOne;
Note that your second example was close, but the IF() function always takes three arguments, so it would have had to be COUNT(IF(kind=1,1,NULL)). I prefer the SUM() syntax shown above because it's concise.
You can also use SUM + IF which is shorter than SUM + CASE:
SELECT
count(id)
, SUM(IF(kind=1, 1, 0)) AS countKindOne
, SUM(CASE WHEN kind=2 THEN 1 ELSE 0 END) AS countKindTwo
There is a slight difference between the top answers, namely SUM(case when kind = 1 then 1 else 0 end) and SUM(kind=1).
When all values in column kind happen to be NULL, the result of SUM(case when kind = 1 then 1 else 0 end) is 0, whereas the result of SUM(kind=1) is NULL.
An example (http://sqlfiddle.com/#!9/b23807/2):
Schema:
CREATE TABLE Table1
(`first_col` int, `second_col` int)
;
INSERT INTO Table1
(`first_col`, `second_col`)
VALUES
(1, NULL),
(1, NULL),
(NULL, NULL)
;
Query results:
SELECT SUM(first_col=1) FROM Table1;
-- Result: 2
SELECT SUM(first_col=2) FROM Table1;
-- Result: 0
SELECT SUM(second_col=1) FROM Table1;
-- Result: NULL
SELECT SUM(CASE WHEN second_col=1 THEN 1 ELSE 0 END) FROM Table1;
-- Result: 0
From MYSQL I solved the problem like this:
SUM(CASE WHEN used = 1 THEN 1 ELSE 0 END) as amount_one,
Hope this helps :D
It is worth noting that you can build upon Gavin Toweys answer by using multiple fields from across your query such as
SUM(table.field = 1 AND table2.field = 2)
You can also use this syntax for COUNT and I am sure other functions as well.