SQL IF statement with a print - mysql

What am I doing wrong? It needs to display yes if more people are single than married and no if viceversa. I just want it to display yes or no only.
IF
select COUNT(StudMaritalStatus) from students WHERE StudMaritalStatus = "M"
<
select COUNT(StudMaritalStatus) from students WHERE StudMaritalStatus = "S"
Print 'Yes'
ELSE
Print 'No';

You want something like this:
select case when married >= single then 'M' else 'S' end
from
(
select sum(case when StudMaritalStatus = 'M' then 1 else 0 end) married
, sum (case when StudMaritalStatus = 'S' then 1 else 0 end) single
from students
) derivedTable
Tie breaking depends on your business requirements, which none of us know.

well considering that MySQL uses:
IF expression THEN
expression
ELSE
ENDIF;
you would be better of not doing it with a select statement
DECLARE married int, single int
SET married = select COUNT(StudMaritalStatus) from students WHERE StudMaritalStatus = 'M'
SET single = select COUNT(StudMaritalStatus) from students WHERE StudMaritalStatus = 'S'
IF married < single THEN
PRINT 'YES'
ELSE
PRINT 'NO'
END IF
In answer yes your syntax was wrong
https://dev.mysql.com/doc/refman/5.7/en/if.html

Related

Diffrence between sum of two products > 0

I want to select the sum of T_No where Transactions are equal to R and subtract it by T_No where Transactions are equal to D and the answer of this should greater than zero for a CustomerID which would be a input (an int input declared in a stored procedure)
((Sum(T_No) where Transactions = R - Sum(T_No) where Transactions = D ) > 0) where CoustomerID = #input
Example : for ID = 1 it would be ((20+15) - 10) > 0
I Have tried so many things but either syntax is wrong, wrong value or it does not accept, and I am literally Stuck, this was my final attempt
SELECT
(select ( select Sum(T_No) where Transactions = R) - (select Sum(T_No) where Transactions = D) as C_T )
FROM CustomerTrans WHERE C_T > 0 ;
Conditional aggregation should help:
SELECT
SUM(CASE WHEN Transaction = 'R' THEN t_no ELSE 0 END) - SUM(CASE WHEN Transaction = 'D' THEN t_no ELSE 0 END)
FROM CustomerTrans
WHERE CoustomerID = #yourCustomerIdVariable
As you're writing a sproc you can assign the result of this to a variable and then decide what to do if the result is negative. (I would personally log an error for example, rather than just hide those results). If the result is null, then there were no transactions for that customer
ps; I used Transaction because that's what your screenshot showed, and I figured a screenshot is less likely to contain a typo than code with syntax errors. Adjust if required
you where kinda close, I would sum like you, only the syntax is a bit off, you can't have aggregate fields in Where, thats why you should use having, also case when syntax is not correct.
Select
CoustomerID,
Sum(case when Transactions = 'R' then T_No else 0 end) -
Sum(case when Transactions = 'D' then T_No else 0 end) as C_T
FROM CustomerTrans
group by CoustomerID
having (Sum(case when Transactions = 'R' then T_No else 0 end) -
Sum(case when Transactions = 'D' then T_No else 0 end))>0

Return 1 or 0 in SQL depending on the multiple statements

If I find that some of the user exists with such a parameters, I want to get 1 otherwise 0. In the future I'll have to add more blocks. But it doesn't seem to work now. What am I doing wrong?
SELECT CAST(CASE WHEN EXISTS(SELECT 1
FROM Customers
WHERE Country = 'France' AND PostalCode%2 = 0)
OR (WHERE Country = 'Germany' AND PostalCode%2 = 0))
)
THEN 1
ELSE 0
END AS BIT)
You need two separate exists:
SELECT CAST(CASE WHEN EXISTS (SELECT 1
FROM Customers
WHERE Country = 'France' AND PostalCode%2 = 0
)
THEN 1
WHEN EXISTS (SELECT 1
FROM Customers
WHERE Country = 'Germany' AND PostalCode%2 = 0
)
THEN 1
ELSE 0
END AS BIT)
Actually, I broke this into two separate THEN clauses. This is almost equivalent to using OR, but because the logic is inside a CASE, THEN seems more natural. (The difference is that the optimizer could choose to re-arrange the OR conditions, but the THEN conditions are executed in lexical order.)
If your statements are actually this simple, you can combine them as:
SELECT CAST(CASE WHEN EXISTS (SELECT 1
FROM Customers
WHERE Country IN ('France', 'Germany') AND PostalCode%2 = 0
)
THEN 1
ELSE 0
END AS BIT)
It looks to me like you're just having issues with your bracketing:
SELECT CAST(
CASE WHEN EXISTS(
SELECT 1
FROM Customers
WHERE (Country = 'France' AND PostalCode%2 = 0)
OR (Country = 'Germany' AND PostalCode%2 = 0)
) THEN 1 ELSE 0 END AS BIT)
Building on Gordon's assumption that PostalCode%2 = 0 for all tested 'sets' of conditionals (you haven't said as much yet), you could likewise shorten this to:
SELECT CAST(
CASE WHEN EXISTS(
SELECT 1
FROM Customers
WHERE PostalCode%2 = 0
AND Country IN ('France', 'Germany')
) THEN 1 ELSE 0 END AS BIT)

Not able to alias column name in nested case using sql query

In this code its able to alias each case statement separately like,
SELECT
id,
SUM(CASE
WHEN (a.place = 'CHN' AND a.salary = 20000)
THEN '1'
ELSE '0'
END) AS '20K Salary',
SUM(CASE
WHEN (a.place = 'CHN' and a.salary = 35000)
THEN '1'
ELSE '0'
END) AS '35K Salary'
FROM Employee a;
but when nested CASE statement is used,
SELECT
id,
SUM(CASE
WHEN (a.place = 'CHN')
THEN (CASE
WHEN a.salary = 20000
THEN '1'
ELSE '0'
END) AS '20K Salary',
(CASE
WHEN a.salary = 35000
THEN '1'
ELSE '0'
END) AS '35K Salary'
END)
FROM Employee a;
its not possible to execute the query
In the first set of code each case statement is part of the SELECT list (i.e. they are in a comma separated list following SELECT) so each returns a column. In the second set of code there is only one case statement in the SELECT list, the fact that it is nested has no impact on this. Also the syntax for the nested case isn't correct because the THEN part is followed by two expressions separated by commas which is not allowed.
Of course this is possible to do what you want. You want to create two columns, so each needs its own logic and its own alias:
SELECT id,
SUM(CASE WHEN a.place = 'CHN' AND a.salary = 20000 THEN 1 ELSE 0
END) as Salary_20K,
SUM(CASE WHEN a.place = 'CHN' AND a.salary = 35000 THEN 1 ELSE 0
END) as Salary_35K
FROM Employee a;
Note: Don't put numeric constants in single quotes. Only use single quotes for string and date constants.

Excluding email lists while selecting specific values at once

I am trying to do 2 things here within 1 SELECT query (I know I could do this in 2 steps but I want to avoid intermediary tables):
Select specific values (M and W only — there are other values possible but I just want these 2 and not other) from a TABLE 'anothertable'.
While avoiding selecting opt-outs and bounced emails (11k rows, <5 columns).
I am not sure if the syntax is correct since the query is loading for ever. Size should not be an issue though (27k rows, <5 columns and 2 core processors).
BEGIN
CREATE TABLE `mytable` AS (
SELECT * FROM `anothertable` A
WHERE NOT EXISTS (SELECT Email FROM `optout` B WHERE B.Email = A.Email)
AND NOT EXISTS (SELECT Email FROM `allbounced` C WHERE C.emailbounced = A.Email)
GROUP BY Email
HAVING
(SUM(CASE WHEN target = 'M' THEN 1 ELSE 0 END) > 0 OR -- MAN is present
SUM(CASE WHEN target = 'W' THEN 1 ELSE 0 END) > 0 AND -- WOMAN is present
SUM(CASE WHEN target NOT IN ('M', 'W') THEN 1 ELSE 0 END) = 0) -- only MAN or WOMAN
);
END
When possible you should use NOT IN instead of NOT EXISTS. This should be faster:
BEGIN
CREATE TABLE `mytable` AS (
SELECT Email FROM `anothertable` A
WHERE Email NOT IN (SELECT Email FROM `optout`)
AND Email NOT IN (SELECT emailbounced FROM `allbounced`)
GROUP BY Email
HAVING
(SUM(CASE WHEN target = 'M' THEN 1 ELSE 0 END) > 0 OR -- MAN is present
SUM(CASE WHEN target = 'W' THEN 1 ELSE 0 END) > 0 AND -- WOMAN is present
SUM(CASE WHEN target NOT IN ('M', 'W') THEN 1 ELSE 0 END) = 0) -- only MAN or WOMAN
);
END

get count of two table fields in one query

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.