How to write query for this? - mysql

Hi friends I have a table like this
ID bid sub_bid cid sub_cid
1 0 2 1 0
2 5 0 3 0
3 3 0 0 4
4 2 0 4 0
on that table either (bid or sub_bid) OR (cid or sub_cid) will be null. I have to write a query for fetching like this..
if bid is zero then I have to take sub_bid or sub_bid is zero then I have to take bid
same incase of cid also.
How can I give this kind of a condition in my mysql query. any one can help me please.
thanks

Have a look at the CASE WHEN statement:
SELECT
CASE WHEN bid is NULL or bid = 0
sub_bid
ELSE
bid end
as abid
http://dev.mysql.com/doc/refman/5.0/en/case-statement.html
http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html

You can use the MySQL if statements for this. Check this

Related

How do I subtract from one column if a specific condition is met in MySQL?

I have a table with three columns
ID
Match_A
Match_B
ABC123
1
1
DEF111
0
1
QRS222
1
1
You can see ID 'ABC123' has a Match (as determined by 1) in both the Match_A and Match_B column. If their is a 1 in both of those columns, I am needing to write a formula that changes at least one of those columns into a 0. It doesn't matter if it's Match_A or Match_B.
The output for this ID would then turn into this.
ID
Match_A
Match_B
ABC123
1
0
Essentially, a match can happen in both columns, but for this report managers do not want it to be counted twice so one column has to be changed to 0 if a situation like this happens.
Any help is appreciated here! Thank you!
So a CASE should get you to the result I think you want
SELECT unique_id, match_a,
case when match_a = 1 AND match_a = match_b
then 0
else match_b
end as match_b
from table

Count of past instances in an appended table

This is my desired output:
CampaignName CampaignDate UsersTargeted CountOfUsersBought
2x1 2018-11-24 1 (UserId 2) 1 (UserId 2)
3x2 2018-11-25 2 (Both) 1 (UserId 1)
'CountOfUsersBought' I want it to be Amongst All Targeted Users.
And the Table (Updated Daily) from where I get the data to fill the previous output has the following structure:
UserId EligibleForOffer(0,1) BoughtToday(0,1) Timestamp
1 0 0 2018-11-24
1 1 0 2018-11-25
1 1 1 2018-11-26
1 0 0 2018-11-27
2 1 0 2018-11-24
2 1 1 2018-11-25
2 1 0 2018-11-26
2 0 1 2018-11-27
I want to store on the variable 'CountOfUsersBought' the count of all the users that actually bought, not only today but all time. How would you go about doing this query?
Please note that users also buy without an offer, so I only want to count the past instances WHERE EligibleForOffer = 1 AND BoughtToday = 1 AND Timestamp <= 'CampaignDate'+ 1 day
I know for another table the users that are targeted for each campaign, I just want to keep for more than 'today' the count of users that took the offer that was given to them.
You can GROUP BY dates and use SUM the find how many users eligible for campaigns and use CASE to do your conditions. And bonus is MIN to find which specific user related with the condition is only one user match.
CREATE TABLE Campain
(
UserId INT
,EligibleForOffer BIT
,BoughtToday BIT
,Timestamp DATE
)
INSERT INTO Campain
VALUES
(1,0,0,'2018-11-24')
,(1,1,0,'2018-11-25')
,(1,1,1,'2018-11-26')
,(1,0,0,'2018-11-27')
,(2,1,0,'2018-11-24')
,(2,1,1,'2018-11-25')
,(2,1,0,'2018-11-26')
,(2,0,1,'2018-11-27')
SELECT Timestamp
,SUM(CAST(EligibleForOffer AS INT)) NumberOfUsersTargeted
,CASE WHEN SUM(CAST(EligibleForOffer AS INT))=1 THEN 'UserId-'+CAST(MIN(UserId) AS VARCHAR) WHEN SUM(CAST(EligibleForOffer AS INT))>1 THEN 'Multiple Users(Both)' ELSE 'No Target' END UsersTargetedDetail
,SUM(CAST(BoughtToday AS INT)) NumberOfBought
,CASE WHEN SUM(CAST(BoughtToday AS INT))=1 THEN 'UserId-'+CAST(MIN(UserId) AS VARCHAR) WHEN SUM(CAST(BoughtToday AS INT))>1 THEN 'Multiple Users(Both)' ELSE 'No Buying' END BoughtDetail
FROM Campain
GROUP BY Timestamp

Combining multiple columns into one- SQL Server 2008

I am trying to make one table value function in Sql Server. Here I have 3 columns and i want to merge them into one column lets say "new". This new column should show the name of 3 columns if they have value as 1.For example for row one it should display Isprod, for row 2 it should display IsCompetProd and so on.
IsProd IsCompetProd IsOther
1 0 0
0 1 0
0 0 1
1 0 0
Is there any way to do that?
Try like this
SELECT CASE WHEN IsProd=1 THEN 'IsProd'
WHEN IsCompetProd=1 THEN 'IsCompetProd'
WHEN IsOther=1 THEN 'IsOther'
END [New]
FROM table1
If I am getting what you want. Use a case statement. Try this:
SELECT
tbl.*,
(
CASE
WHEN IsProd=1
THEN 'IsProd'
WHEN IsCompetProd=1
THEN 'IsCompetProd'
WHEN IsOther=1
THEN 'IsOther'
ELSE 'None'
END
)AS newColumn
FROM
tbl

Understanding GROUP BY clause

SELECT a,b from <table_name> GROUP BY a,b,c.
Is the above a valid sql statement?
Not without a table name it is not. If it had a table name it would be valid, but probably not very useful.
Typically one would use GROUP BY clauses in conjunction with some aggregate function (SUM, COUNT, MAX, MIN, etc.) to derive some values related to the grouped fields.
Yes, that query is legal SQL. Whether it's useful SQL is another matter entirely.
The query
select a , b
from foo
group by a,b,c
Does the following:
groups the rows from the source table into distinct groups, 1 for each unique combination of columns a, b and c.
Each such group is then collapsed into a single row containing the grouping columns and the values of any required aggregate functions required by the query.
The resulting result set is then returned to the caller, tossing any unwanted columns (in this case, column c).
Since one of the grouping columns is discarded, the specified query is not guaranteed to be a set of unique rows. It might well contain duplicates. For instance, if group by came up with these groups to be returned:
A B C
- - -
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
The results set returned by the query would be
A B
- -
0 0
0 0
0 1
0 1
1 0
1 0
1 1
1 1
And so, not necessarily useful.
If you include a table name I guess you're asking if you can group by an unselected element c. Yes you can.
No - You need a table.
SELECT a,b FROM myTable GROUP BY a,b,c
where myTable is the table you are selecting from (which must have columns a,b and c).
No- because you didn't specify a table name. If you had, then yes, it's certainly valid for mysql, not sure about Oracle (which validates GROUPing very differently). But it doesn't make any sense...
a b c
0 0 0
0 0 1
0 1 0
0 1 1
applying the query to the table above will give:
0 0
0 0
0 1
0 1
And I don't see how that would be a meaningful result - if you don't want an aggregate value, then DISTINCT makes more sense - but gives a different result:
SELECT DISTINCT a, FROM `atable`
0 0
0 1
Maybe if you explained the real reason youwere asking the question we could make a more sensible attempt at answering it.

MySQL Query: count entries by status

I have a log table with following schema:
OperatorId - JobId - Status ( Good/Bad/Ugly )
Alex 6 Good
Alex 7 Good
James 6 Bad
Description: Whenever an operator works on a job, an entry is made along with Status. That's it.
Now I need a report like:
OperatorId - Good Count - Bad Count - Ugly Count
Alex 2 0 0
James 0 1 0
select operatorid,
sum(if(status="good",1,0)) as good,
sum(if(status="bad",1,0)) as bad,
sum(if(status="ugly",1,0)) as ugly
from table
group by operatorid
This is called a Pivot Table. It is done by setting a value 1 or 0 for each state and then summing them up:
SELECT
T.OperatorId,
SUM(T.GoodStat) AS Good,
SUM(T.BadStat) AS Bad,
SUM(T.UglyStat) AS Ugly
FROM
(
SELECT
CASE WHEN Status = 'Good' THEN 1 ELSE 0 END AS GoodStat,
CASE WHEN Status = 'Bad' THEN 1 ELSE 0 END AS BadStat,
CASE WHEN Status = 'Ugly' THEN 1 ELSE 0 END AS UglyStat,
OperatorId
FROM logTable T
)
GROUP BY T.OperatorId
If, like me, you prefer, whenever possible, to calculate counts with COUNT rather than with SUM, here's an alternative solution, which uses a method asked about in this thread:
SELECT
operatorid,
COUNT(status = 'good' OR NULL) as good,
COUNT(status = 'bad' OR NULL) as bad,
COUNT(status = 'ugly' OR NULL) as ugly
FROM table
GROUP BY operatorid