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%'
Related
I am trying to connect two tables with left join and a date.
My SQL Query
SELECT
ord.`ordernumber` bestellnummer,
his.`change_date` zahldatum
FROM
`s_order` ord
LEFT JOIN
`s_order_history` his ON ((ord.`id`=his.`orderID`) AND (ord.`cleared`=his.`payment_status_id`)) #AND MIN(his.`change_date`)
WHERE
ord.`ordertime` >= \''.$dateSTART.'\' AND ord.`ordertime` <= \''.$dateSTOP.'\'' ;
s_order
+----+---------------------+---------+-------------+
| id | ordertime | cleared | ordernumber |
+----+---------------------+---------+-------------+
| 1 | 2014-08-11 19:53:43 | 2 | 123 |
| 2 | 2014-08-15 18:33:34 | 2 | 125 |
+----+---------------------+---------+-------------+
s_order_history
+----+-------------------+-----------------+---------+---------------------+
| id | payment_status_id | order_status_id | orderID | orderID change_date |
+----+-------------------+-----------------+---------+---------------------+
| 1 | 1 | 5 | 1 | 2014-08-11 20:53:43 |
| 2 | 2 | 5 | 1 | 2014-08-11 22:53:43 |
| 3 | 2 | 7 | 1 | 2014-08-12 19:53:43 |
| 4 | 1 | 5 | 2 | 2014-08-15 18:33:34 |
| 5 | 1 | 6 | 2 | 2014-08-16 18:33:34 |
| 6 | 2 | 6 | 2 | 2014-08-17 18:33:34 |
+----+-------------------+-----------------+---------+---------------------+
Wanted result:
+-------------+---------------------+
| ordernumber | change_date |
+-------------+---------------------+
| 123 | 2014-08-11 22:53:43 |
| 125 | 2014-08-17 18:33:34 |
+-------------+---------------------+
The problem I have is getting only the date, where the cleared/payment_status_id value has been changed in s_order. I currently get all dates where the payment_status_id matches the current cleared value, but I only need the one, where it happend first.
This is only an excerpt of the actually query, since the original is a lot longer (mostly more left joins and a lot more tables).
You can group data by ordernumber
SELECT
ord.`ordernumber` bestellnummer,
MIN(his.`min_change_date`) as zahldatum
FROM
`s_order` ord
LEFT JOIN
`s_order_history` his ON ((ord.`id`=his.`orderID`) AND (ord.`cleared`=his.`payment_status_id`)) #AND MIN(his.`change_date`)
WHERE
ord.`ordertime` >= \''.$dateSTART.'\' AND ord.`ordertime` <= \''.$dateSTOP.'\''
GROUP BY
ord.`ordernumber`;
or you can group data in a subquery:
SELECT
ord.`ordernumber` bestellnummer,
his.`min_change_date` zahldatum
FROM
`s_order` ord
LEFT JOIN (
SELECT
orderID, payment_status_id, MIN(change_date) as min_change_date
FROM
s_order_history
GROUP BY
orderID, payment_status_id
) his ON (ord.`id` = his.`orderID` AND ord.`cleared` = his.`payment_status_id`)
WHERE
ord.`ordertime` >= \''.$dateSTART.'\' AND ord.`ordertime` <= \''.$dateSTOP.'\'';
Try this:
select s_order.ordernumber, min(s_order_history.change_date)
from s_order left join s_order_history
on s_order.id = s_order_history.orderID
and s_order.cleared = s_order_history.payment_status_id
group by s_order.order_id
SELECT ord.`ordernumber` bestellnummer,
MIN( his.`change_date` ) zahldatum
...
GROUP BY ord.`ordernumber`
MIN is an aggregate function so you can't use it in a JOIN straight up like you've tried above. You also are not comparing it to a value in your JOIN.
You'll want to do something like:
his.`change_date` = (SELECT MIN(his.`change_date`) FROM s_order_history where ord.`id` = his.`orderID`)
in your JOIN.
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;
I am not the greatest at SQL and I am trying to achieve the following:
I have a table with columns like so:
id | cup_type | cup_id | name
I have a ton of records in the database which will have the same cup_id but different cup_types
I would really like to select records that have the same cup_id but different cup_types
id | cup_type | cup_id | name
1 | TypeOne | 12 | NameOne
2 | TypeTwo | 12 | NameTwo
3 | TypeOne | 13 | NameThree
4 | TypeTwo | 13 | NameFour
5 | TypeOne | 14 | NameFive
6 | TypeOne | 14 | NameSix
When I run the said query it would being me back the following:
id | cup_type | cup_id | name
1 | TypeOne | 12 | NameOne
2 | TypeTwo | 12 | NameTwo
3 | TypeOne | 13 | NameThree
4 | TypeTwo | 13 | NameFour
I hope I have explained this ok and let me know if more clarity is needed.
This query would do the trick
select * from
yourtable a
join (select cup_id, count(distinct cup_type) nbType
from yourTable
group by cup_id) b using(cup_id)
where b.nbType >= 2;
Get a result set from your table where you count the distinct cup_type.
Group that result set by cup_id.
Keep the cup_id so we can join on the same table, using that id.
Return only those where the count of distinct types was at least two.
Try something like this:
select a.id, b.id ....... from t1 as a, t2 as b where a.cup_id=b.cup_id and a.cup_type !=b.cup_type
Its very hard for to set a proper title, because I dont know how I describe my problem.
I have a table like this:
dlID | dl_seID | dlEpisode | dlFlag
___________________________________
1 | 1 | 1 | 0
2 | 1 | 2 | 1
3 | 1 | 3 | 1
4 | 2 | 1 | 1
5 | 2 | 2 | 0
6 | 3 | 1 | 0
What i want is a select query where I get something like this:
dlID | dl_seID | dlEpisode | dlFlag | dlFlagCount
_________________________________________________
1 | 1 | 1 | 0 | 2
2 | 1 | 2 | 1 | 2
3 | 1 | 3 | 1 | 2
4 | 2 | 1 | 1 | 1
5 | 2 | 2 | 0 | 1
6 | 3 | 1 | 0 | 0
dlFlagCount shoud be a counter of dlFlag = 1 where dl_seID = dl_seID.
Second try:
I need a value where I see how many Flags have the value 1 with the same dl_seID.
Is that possible?
I hope you guys know what I want^^
Regards
Try this:
select
a.*,
ifnull(b.ctflags,0)
from
tablea a left join
( select dl_seID, count(dlFlag) ctflags
from tablea
where dlFlag=1
group by dl_seID ) b on (a.dl_seID = b.dl_seID)
The left join is just to get the registry with 0 flags
See the fiddle: http://sqlfiddle.com/#!2/ef9b0/5
EDIT:
As op requested some explanation, here it goes:
What you asked is to count the amount of flags by the dl_seID and to do that you need to do this you separeta your problems, first you get the count for the dl_seID by flags, this is this subquery:
select dl_seID, count(dlFlag) ctflags
from tablea
where dlFlag=1
group by dl_seID
This became a 'separe table' or a new group of data, whatever you wanna call it. Then you have to join this with your original data (from your table) like the query for answer.
The left join part is because maybe there are some data that wont complain with where dlFlag=1 therefore if you want to get then as 0 you have to bring all values from table that exists or not on our created subgroup. And this ifnull(b.ctflags,0) is for theese data data exists on your table but has no flags (for your problem). If you use just b.ctflags it will bring null.
SELECT x.*
, COALESCE(y.flagcount,0) flagcount
FROM my_table x
LEFT
JOIN
( SELECT seID
, COUNT(*) flagcount
FROM my_table
WHERE flag = 1
GROUP
BY seid
) y
ON y.seid = x.seid;
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;