How i can add more condition to mysql query? - mysql

Table name is Sample
id name status date
1 ddd 1 2015-03-11
2 dddd 1 2015-03-12
3 dfdfgfg 0 2015-03-11
4 ererre 1 2015-03-19
5 eeeerer 0 2015-03-03
Here is the table, - this is query I am adding to get the result. I want the result from the table where date should not be expired if the status is set to 1 and no condition if the status is zero. So it should display. So I made the query like this
select * from sample where status='1' AND date>Now() OR status='0'
I am getting the result as like this which is correct
3 dfdfgfg 0 2015-03-11
4 ererre 1 2015-03-19
5 eeeerer 0 2015-03-03
But I want to add more queries to the same, how i can add more condition to above query?

You have to put the old condition and the new one in parenthesis , then use an AND to link them:
select * from sample
where (status='1' AND date>Now() OR status='0')
AND (new condition 1)
AND (new condition 2) ...

SELECT * FROM TABLE_NAME WHERE expiry_date > NOW()

Try using Union / Union All which soever suffice your requirement
Sample code with example from your data
create table sample(id INT,name CHAR(10), status INT, date_e DATE);
INSERT INTO sample VALUES(1, 'ddd',1,'2015-03-11');
INSERT INTO sample VALUES(2, 'dddd',1,'2015-03-12');
INSERT INTO sample VALUES(3, 'dfdfgfg',0,'2015-03-11');
INSERT INTO sample VALUES(4, 'ererre',1,'2015-03-19');
INSERT INTO sample VALUES(5, 'eeeerer',0,'2015-03-03');
SELECT * FROM sample;
+------+---------+--------+------------+
| id | name | status | date_e |
+------+---------+--------+------------+
| 1 | ddd | 1 | 2015-03-11 |
| 2 | dddd | 1 | 2015-03-12 |
| 3 | dfdfgfg | 0 | 2015-03-11 |
| 4 | ererre | 1 | 2015-03-19 |
| 5 | eeeerer | 0 | 2015-03-03 |
+------+---------+--------+------------+
5 rows in set (0.00 sec)
mysql> select * from sample where status='1' AND date_e>Now()
-> UNION ALL
-> select * from sample where status='0';
+------+---------+--------+------------+
| id | name | status | date_e |
+------+---------+--------+------------+
| 4 | ererre | 1 | 2015-03-19 |
| 3 | dfdfgfg | 0 | 2015-03-11 |
| 5 | eeeerer | 0 | 2015-03-03 |
+------+---------+--------+------------+
3 rows in set (0.00 sec)

Related

MySQL: select and divide by count using group by

Here's a data set of my table
ID |groupID| Start | End | SegStart | SegEnd | something
-------------------------------------------------------------------
1 | 1 | 0.234 | 0.345 | 0.345 | 0.677 | 0
2 | 1 | 0.234 | 0.345 | 0.346 | 0.678 | 0
3 | 1 | 0.234 | 0.345 | 0.347 | 0.679 | 0
4 | 1 | 0.234 | 0.345 | 0.348 | 0.680 | 1
5 | 2 | 0.345 | 0.567 | 0.568 | 0.570 | 0
6 | 2 | 0.345 | 0.567 | 0.569 | 0.571 | 1
7 | 3 | 0.567 | 0.678 | 0.679 | 0.681 | 0
8 | 3 | 0.567 | 0.678 | 0.680 | 0.682 | 0
9 | 3 | 0.567 | 0.678 | 0.681 | 0.683 | 1
I want to calculate a value from the Start / End columns as well as the SegStart / SegEnd columns where something = "1" and then divide this value by the number of items in a group (group 1 has 4 items, group 2 has 2, group 3 has 3, etc)
I've tried this query, but it gives me the error "Subquery returns more than 1 row"
select (((End - Start) - (SegEnd - SegStart)) /
(select count(*) as NumSeg from table group by groupID)) as NewValue
from table where something = "1";
I would like a list of the new value for each group, kind of like this (values are imaginary):
groupID | NewValue
--------------------
1 | 0.102
2 | 0.110
3 | 0.036
You could try this:
CREATE TABLE mytable(
ID INTEGER NOT NULL PRIMARY KEY
,groupID INTEGER NOT NULL
,Start NUMERIC(11,3) NOT NULL
,End NUMERIC(7,3) NOT NULL
,SegStart NUMERIC(11,3) NOT NULL
,SegEnd NUMERIC(11,3) NOT NULL
,something BIT NOT NULL
);
INSERT INTO mytable(ID,groupID,Start,End,SegStart,SegEnd,something) VALUES (1,1,0.234,0.345,0.345,0.677,0);
INSERT INTO mytable(ID,groupID,Start,End,SegStart,SegEnd,something) VALUES (2,1,0.234,0.345,0.346,0.678,0);
INSERT INTO mytable(ID,groupID,Start,End,SegStart,SegEnd,something) VALUES (3,1,0.234,0.345,0.347,0.679,0);
INSERT INTO mytable(ID,groupID,Start,End,SegStart,SegEnd,something) VALUES (4,1,0.234,0.345,0.348,0.680,1);
INSERT INTO mytable(ID,groupID,Start,End,SegStart,SegEnd,something) VALUES (5,2,0.345,0.567,0.568,0.570,0);
INSERT INTO mytable(ID,groupID,Start,End,SegStart,SegEnd,something) VALUES (6,2,0.345,0.567,0.569,0.571,1);
INSERT INTO mytable(ID,groupID,Start,End,SegStart,SegEnd,something) VALUES (7,3,0.567,0.678,0.679,0.681,0);
INSERT INTO mytable(ID,groupID,Start,End,SegStart,SegEnd,something) VALUES (8,3,0.567,0.678,0.680,0.682,0);
INSERT INTO mytable(ID,groupID,Start,End,SegStart,SegEnd,something) VALUES (9,3,0.567,0.678,0.681,0.683,1);
select A.GROUPID, ((End - Start) - (SegEnd - SegStart)) / B.NumSeg AS V1
from mytable A
INNER JOIN (select GROUPID, count(*) as NumSeg from mytable group by GROUPID) B ON A.GROUPID = B.GROUPID
where something = "1";
Output:
GROUPID V1
1 1 -0,0552500
2 2 0,1100000
3 3 0,0363333

if with yes or no status mysql query

I have 2 tables, the first table or_f_table data. The second table or_table
or_f_table
f_id | f_o_id | f_u_id
1 | 19 | 1
2 | 5 | 2
3 | 19 | 2
or_table
o_id | o_name
4 | test1
5 | test2
19 | oops2
20 | oops3
SELECT o.o_name,
IF ((SELECT count(*) FROM or_f_table as f
WHERE f.f_u_id = 1 ),'Yes','No') as follow_status
FROM or_table as o
WHERE o.o_name LIKE '%oop%'
I want to do something like this result :-
o_name | follow_status
oops2 | Yes
oops3 | No
I am getting result
o_name | follow_status
oops2 | Yes
oops3 | Yes
Why doesn't it work? And how should I correct it
There will always be a value greater than 0 for your where condition. That is why it is not working.
Try this to get the specified results
SELECT o.o_name,
IF ((SELECT count(*) FROM or_f_table as f
WHERE f.f_o_id = o.o_id ),'Yes','No') as follow_status
FROM or_table as o
WHERE o.o_name LIKE '%oop%'

Selecting multiple unrelated data from two tables and insert into one table mysql

This is my scenario
I have a permissions table with the following fields.
id | module | permission
1 | client | add
2 | client | edit
3 | client | delete
4 | someth | edit
5 | someth | delete
employee table
id | status | somestatus
1 | act | 1
2 | den | 1
3 | act | 0
4 | den | 1
5 | act | 0
6 | act | 1
Now what i would need to do is select the employee who have status="act" and somestatus=1 and give them all permissions where module="client"
so the table employee_permissions should have these rows
id | empid | permid | permvalue
1 | 1 | 1 | 1
2 | 1 | 2 | 1
3 | 1 | 3 | 1
1 | 6 | 1 | 1
2 | 6 | 2 | 1
3 | 6 | 3 | 1
This is the query I tried and I'm stuck here
INSERT INTO at2_permission_employee (employee_id,permission_id)
SELECT at2_employee.employee_id as employee_id
, (SELECT at2_permission.permission_id as permission_id
FROM at2_permission
where at2_permission.permission_module='client'
)
from at2_employee
where at2_employee.employee_status='Active'
and at2_employee.employees_served_admin = 1;
I get the error sub query returns multiple rows which makes sense to me. But I'm not sure how to modify the query to account for iterating over the rows returned by sub query
If I'm not wrong, like this:
INSERT INTO at2_permission_employee (employee_id, permission_id, permvalue)
SELECT
at2_employee.employee_id,
at2_permission.permission_id,
1
FROM at2_permission cross join at2_employee
WHERE
at2_employee.employee_status='Active'
and at2_employee.employees_served_admin = 1
and at2_permission.permission_module='client';
It's a bit unclear where the value for permvalue should come from so I hard coded it and used the permission.id for both id and permid, but this query should give you an idea on how to accomplish what you want:
insert employee_permissions (id, empid, permid, permvalue)
select p.id, e.id, p.id, 1
from employee e, permissions p
where p.module = 'client' and e.status = 'act' and e.somestatus = 1;

how to create a counting column for a particular item

I have the following schema (mysql)
create table test(
userid int(11) not null,
item varchar(15),
bookid int(11));
insert into test values ('1','journal',NULL);
insert into test values ('1','journal',NULL);
insert into test values ('1','book',NULL);
insert into test values ('2','book',NULL);
insert into test values ('2','journal',NULL);
insert into test values ('1','book',NULL);
insert into test values ('2','journal',NULL);
insert into test values ('3','book',NULL);
insert into test values ('1','book',NULL);
insert into test values ('1','journal',NULL);
insert into test values ('3','journal',NULL);
insert into test values ('1','journal',NULL);
insert into test values ('2','journal',NULL);
insert into test values ('2','book',NULL);
insert into test values ('2','journal',NULL);
insert into test values ('1','journal',NULL);
insert into test values ('3','book',NULL);
insert into test values ('3','book',NULL);
insert into test values ('3','book',NULL);
insert into test values ('3','book',NULL);
whenever there is a book, I'm trying assign an auto increment beginning with 1 in the bookid column. For each user, the numbering begins again from 1. I know a way this can be done by creating a separate table. Is there a way I can avoid that and accomplish that using some sort of update query in this very table and update the column bookid? I am trying to get output similar to the following:
userid,item,bookid
'1','journal',NULL
'1','journal',NULL
'1','book',1
'2','book',1
'2','journal',NULL
'1','book',2
'2','journal',NULL
'3','book',1
'1','book',3
'1','journal',NULL
'3','journal',NULL
'1','journal',NULL
'2','journal',NULL
'2','book',2
'2','journal',NULL
'1','journal',NULL
'3','book',2
'3','book',3
'3','book',4
'3','book',5
I appreciate if someone could guide me on how to accomplish this?
Here's one idea...
drop table if exists test;
create table test
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,userid int not null
,item varchar(15) NOT NULL
);
insert into test (userid,item) values
(1,'journal')
,(1,'journal')
,(1,'book')
,(2,'book')
,(2,'journal')
,(1,'book')
,(2,'journal')
,(3,'book')
,(1,'book')
,(1,'journal')
,(3,'journal')
,(1,'journal')
,(2,'journal')
,(2,'book')
,(2,'journal')
,(1,'journal')
,(3,'book')
,(3,'book')
,(3,'book')
,(3,'book');
SELECT x.*
, COUNT(*) rank
FROM test x
JOIN test y
ON y.userid = x.userid
AND y.item = x.item
AND y.id <= x.id
GROUP
BY id
ORDER
BY userid
, item
, rank;
+----+--------+---------+------+
| id | userid | item | rank |
+----+--------+---------+------+
| 3 | 1 | book | 1 |
| 6 | 1 | book | 2 |
| 9 | 1 | book | 3 |
| 1 | 1 | journal | 1 |
| 2 | 1 | journal | 2 |
| 10 | 1 | journal | 3 |
| 12 | 1 | journal | 4 |
| 16 | 1 | journal | 5 |
| 4 | 2 | book | 1 |
| 14 | 2 | book | 2 |
| 5 | 2 | journal | 1 |
| 7 | 2 | journal | 2 |
| 13 | 2 | journal | 3 |
| 15 | 2 | journal | 4 |
| 8 | 3 | book | 1 |
| 17 | 3 | book | 2 |
| 18 | 3 | book | 3 |
| 19 | 3 | book | 4 |
| 20 | 3 | book | 5 |
| 11 | 3 | journal | 1 |
+----+--------+---------+------+
Note that MyISAM actually lets you use a composite PK in which part of that composite is an auto-incrementing id, but InnoDB prohinits this.
On larger datasets a query along these lines will likely be far more efficient...
SELECT id
, userid
, item
, IF(#userid=userid,IF(#item=item,#i:=#i+1,#i:=1),#i:=1) rank
, #userid := userid
, #item := item
FROM test
, (SELECT #userid = NULL,#item:='',#i:=1) vars
ORDER
BY userid,item,id;

mysql - copy entire row to from one table to another and add count(*) with conditions in one query

I got stuck with my problem. After looking on the web and SO i havent found a solution. You are my last hope :) Here's the problem:
I have three tables:
table_tmp
id | name | val | owner |
------------------------
5 | abc | 100 | 3
6 | cde | 200 | 4
table_ready
id | special_number | id_tmp | name_tmp | val_tmp | owner_tmp |
---------------------------------------------------------------
1 | 0 | 1 | xyz | 100 | 3 |
2 | 0 | 2 | zzz | 100 | 4 |
3 | 1 | 3 | kkk | 200 | 3 |
4 | 2 | 4 | uuu | 130 | 3 |
Now i want to copy entire row with owner = 3 from table_tmp to table_ready. It's easy - i do it with:
INSERT INTO table_ready SELECT '', '', t.* FROM table_tmp t WHERE owner = 3;
But i want to have this query to count also all rows from table_ready that have owner_tmp = 3 and val_tmp = 100.
So after query table_ready would look like this:
id | special_number | id_tmp | name_tmp | val_tmp | owner_tmp |
---------------------------------------------------------------
1 | 0 | 1 | xyz | 100 | 3 |
2 | 0 | 2 | zzz | 100 | 4 |
3 | 1 | 3 | kkk | 100 | 3 |
4 | 2 | 4 | uuu | 130 | 3 |
5 | 3 | 5 | abc | 100 | 3 |
What happened? values from table_tmp (name, val and owner) went to table_ready (name_tmp, val_tmp, owner_tmp), id was auto incremented, and special number is effect of query:
SELECT count(id) FROM table_ready WHERE owner_tmp = 3 AND val_tmp = 100.
How to join these queries in one?
FORTUNATELY after writing this post I went to shave my beard and make some tea and I found a solution. I do not need joining those queries at all. If anybody has a solution to question above feel free to write it - i'd be glad to improve my skills. Sorry for disturbing :)
I'm on a plane, so I can't test this right now, but try the following:
INSERT INTO table_ready SELECT '', IFNULL(r.count(distinct id),0) as special_number, t.*,
FROM table_tmp t LEFT OUTER JOIN table_ready r ON t.owner = r.owner_temp
WHERE t.owner = 3 and r.val_tmp = 100 GROUP BY r.owner_temp;
Otherwise, I think you'll have to use a subquery.
Edit: Added IFNULL, not sure if it's necessary.
Well, actually you've some error because you say this query:
SELECT count(id) FROM table_ready WHERE owner_tmp = 3 AND val_tmp = 100
returns 3 and it actually returns 1 given your data.
Anyway, this is the query I think you're looking for:
INSERT INTO table_ready
SELECT '',
(SELECT count(*) FROM table_ready
WHERE owner_tmp = 3 AND val_tmp = 100),
t.* FROM table_tmp t
WHERE owner = 3;