Exctract specific data with self-check - mysql

I have this kind of table with data:
+-------------+------------+------------+
| Name | Test1 | Test2 |
+-------------+------------+------------+
| A | 1 | 1 |
+-------------+------------+------------+
| A | 1 | 1 |
+-------------+------------+------------+
| A | 0 | 2 |
+-------------+------------+------------+
| B | 1 | 1 |
+-------------+------------+------------+
| B | 2 | 1 |
+-------------+------------+------------+
| C | 1 | 1 |
+-------------+------------+------------+
| C | 1 | 1 |
+-------------+------------+------------+
I need to get all names that have all in field test1 and test2 values 1.
In this case output should be like:
+-------------+------------+
| C | PASS |
+-------------+------------+
Because all records whose name is C and have Test1=1 and Test2=1 are passed,
For example record A cannot pass because one of row have Test1=0 and Test=2.
Same is for B. B have only one record with Test1=1 and Test2=1 but the next record for B have Test1=2 and Test2=1.
How to make query that can extract those data? Or this is better to solve through code?

Combine both Test1 and Test2 columns with UNION.
Then select the name which having both minimum and maximum test value as 1.
Query
select name,'PASS' as `status`
from
(
select name,test1 as test
from tests
union all
select name,test2 as test
from tests
)t
group by name
having max(t.test) = 1
and min(t.test) = 1;
SQL Fiddle

My idea is to first choose names that do not fill your rule and then select all remaining ones. Is this your logic?
select distinct name, 'PASS' from table
where name not in
(select name from table where test1 <> 1 or test2 <> 1);

SELECT DISTINCT name, "PASS" FROM yourtable WHERE test1 = 1 AND test2=1

Related

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;

Get the count of data based on id in mysql result

I have a table like the below one
id | id_fk | data |
-------------------------
1 | 2 | data1 |
2 | 2 | data2 |
3 | 1 | data3 |
4 | 3 | data4 |
5 | 1 | data5 |
-------------------------
here I have the table id as 'id', foreign key from another table as id_fk.
What I try to achieve is, to get the count of each foreign key in an increment mode. that is, if the id_fk -> 2 occur on the first time, then the count should be 1, at the next occurance count become 2, and so on for all the id_fk. I tried many ways. But none give me the actual output.
From the above table, the result table will look like:
id_fk | count |
------------------
1 | 1 |
1 | 2 |
2 | 1 |
2 | 2 |
3 | 1 |
------------------
Please help me to solve this.. any help will be appreciated.
Try this
SELECT `id_fk`,
#a:=IF(id_fk=#b,#a+1,1) serial_number,
#b:=id_fk
FROM your_table,(SELECT #a:= 0,#b:=0) AS a
ORDER BY `id_fk` ASC
It works perfect with join.
select t1.id_fk,t1.id,count(*)
from your_table t1
left join your_table t2
on t1.id_fk=t2.id_fk and t1.id>=t2.id
group by t1.id_fk,t1.id
See Sql Fiddle Demo

add a temporary column in SQL, where the values depend from another column

I have this table:
ID | name | result |
--------------------
1 | A | 1 |
--------------------
2 | B | 2 |
--------------------
3 | C | 1 |
--------------------
1 | A | 2 |
--------------------
4 | E | 2 |
--------------------
I want to add a new temporary column next to |result|, and where result=1 the value should be 100, and where result=2 the value should be 80 so it should look like this:
ID | name | result | NewColumn|
-------------------------------
1 | A | 1 | 100 |
-------------------------------
2 | B | 2 | 80 |
-------------------------------
3 | C | 1 | 100 |
-------------------------------
1 | A | 2 | 80 |
-------------------------------
4 | E | 2 | 80 |
-------------------------------
How can I query this in SQL ?
Use a CASE expression in your SELECT's column list - something like this:
SELECT
ID,
name,
result,
CASE
WHEN result = 1 THEN 100
WHEN result = 2 THEN 80
ELSE NULL
END AS NewColumn
FROM YourTable
Add additional WHEN expressions or alter the ELSE expression as needed.
You could add a case statement to your query:
SELECT id, name, result, CASE result WHEN 1 THEN 100 WHEN 2 THEN 80 ELSE NULL END
from my_table
SELECT ID
,name
,result
,NewColumn = CASE WHEN result = 1 THEN 100 WHEN result = 2 THEN 80 END
FROM Table1
As the answers given above are also correct. But I will say that if you have a predefined relation or logic between the existing column and the new column then you can also achieve that without the CASE. Writing CASE for all the possible values would not be possible nor efficient.
For your existing data. I can use it something like this
SELECT ID, name, result, (20*(6-result)) as NewColumn
FROM YourTable
Here I am assuming that 1=>100, 2=>80, 3=>60, 4=>40, 5=>20.
of course this only for understanding purpose. You can create your own expression depending on the actual data.
You would use IF Statement in Mysql
SELECT col1,col2,col3, IF(col3=1,'100', IF(col3=2,80,''))
FROM your_table

MySQL copy column value from several columns to one column

I want to copy the latest information from table 1 into table 2.
For the ID i used
insert into Table2(ID) (Select ID FROM Table2). That was not a problem.
CL1 contains the oldest data.
CL3 contains the newest data. So CL2 is between.
Insert into was probably the easiest way to copy the ID from Table1 to Table2
my problem with MySQL is the following.
Table 1
ID | CL1 | CL2 | CL3
A | 1 | 2 | 3
B | 1 | 2 | NULL
C | 1 | 2 | 3
D | 1 | NULL| NULL
E | 1 | 2 | 3
Table 2
ID | CLX
A |
B |
C |
D |
E |
Result should be:
Table 2
ID | CLX
A | 3
B | 2
C | 3
D | 1
E | 3
use GREATEST().
Assuming that CL1 is not nullable, and CL3 cannot have value unless CL2 is filled up.
INSERT INTO table2(ID, CLX)
SELECT ID, GREATEST(CL1, COALESCE(CL2, CL1), COALESCE(CL3, CL1))
FROM table1
SQLFiddle Demo
Thank you,
Coalesce was the function I need for my queries.
`Select ID, COALESCE(CL3,CL2,CL1) as latest from table1`

how to write this self join based on three columns

Hello there I have a following table
------------------------------------------
| id | language | parentid | no_daughter |
------------------------------------------
| 1 | 1 | 0 | 2 |
------------------------------------------
| 1 | 1 | 0 | 2 |
------------------------------------------
| 2 | 1 | 1 | 1 |
------------------------------------------
| 2 | 2 | 1 | 1 |
------------------------------------------
| 3 | 1 | 1 | 0 |
------------------------------------------
| 3 | 2 | 1 | 0 |
------------------------------------------
| 4 | 1 | 2 | 0 |
------------------------------------------
| 4 | 2 | 2 | 0 |
------------------------------------------
| 5 | 1 | 2 | 0 |
------------------------------------------
| 5 | 2 | 2 | 1 |
-----------------------------------------
| 5 | 1 | 4 | 1 |
------------------------------------------
| 5 | 2 | 4 | 1 |
------------------------------------------
Scenario
Every record has more than one rows in table with different language ids. parentid tells who is the parent of this record. no_daughter columns tells against each record that how many child one record has. Means in Ideal scenario If no_daughter has value 2 of id = 1 , it means 1 should be parentid of 2 records in same table. But If a record has more than one exitance with respect to language, it will be considered as one record.
My Problem
I need to find out those records where no_daughter value is not correct. It means if no_daughter is 2, there must be two records whoes parentid has that id. In above case record with id = 1 is valid. But record having id = 2 is not valid because the no_daughter = 1 but actual daughter of this record is 2. Same is the case with id=4
Can any body tell me how can I find these faulty records?
Updated after answers
Ken Clark has and shola has given answer which return same result for example shola query is
SELECT DISTINCT
id
FROM
tbl_info t
INNER JOIN
(SELECT
parentid,
COUNT(DISTINCT id) AS childs
FROM
tbl_info
GROUP BY parentid) AS parentchildrelation
ON t.id = parentchildrelation.parentid
AND t.no_daughters != parentchildrelation.childs
This query is returning those ids who have been used as parentid somewhere in table but having wrong no_daughter values. But not returning ids that has value in no_daugter columns but have not been used as parentid any where in table. For exampl id = 5 has no_daughter = 1 but it is not used as parentid in table. So it is also a faulty record. But above query is not capturing such records.
Any help will be much appreciated.
Try this:
SELECT DISTINCT
id
FROM
tbl_info t
Left JOIN
(SELECT
parentid,
COUNT(DISTINCT id) AS childs
FROM
tbl_info
GROUP BY parentid) AS parentchildrelation
ON t.id = parentchildrelation.parentid
Where t.no_daughters != parentchildrelation.childs
Try this:
SELECT id FROM tinfo t inner join
(SELECT parentid, COUNT(distinct language ) as childs FROM tinfo group by parentid) as summary
on t.id=summary.parentid and t.no_daughters!= summary.childs
try this
Select Distinct * From tablename t
Left Join
(
Select COUNT(t1.Id) Doughter,t1.parentid,t1.language From tablename t1 Group By t1.parentid,t1.language
)tbl
On t.id=tbl.parentid And tbl.language=t.language And t.no_daughter<>tbl.Doughter