I have 2 tables
Vendor
ID | userid| address | Country
1 | 10 | NY | US
2 | 20 | Mumbai | INDIA
events_todo
ID | events_id| vendor| status
1 | 1 | 10 | Completed
2 | 2 | 20 | Inprogress
So I want to join these 2 tables and get all vendor table data. I want to join on the basis of if userid of vendor table exists in event_todo table's vendor. I also want to show of column of Count if the status is completed. For example:
ID | userid | address | Country | events_id | status | Count
1 | 10 | NY | US | 1 | Completed | 1
2 | 20 | Mumbai | INDIA | 2 | Inprogress| 0
I have applied the following query and I am getting results but not able to get the count of event status
SELECT `vendors`.`id`, `vendors`.`userid`, `vendors`.`address`,`vendors`.`country` AS `updatedAt`, `vendors`.`userid` IN (SELECT sum(events_todo.status) AS completed FROM events_todo ) AS `completed`, `events_todo`.`id` AS `events_todo.id`, `events_todo`.`events_id` AS `events_todo.events_id`, `events_todo`.`category` `events_todo.vendor`, `events_todo`.`created_by` `events_todo.status` FROM `vendors` AS `vendors` LEFT OUTER JOIN `events_todo` AS `events_todo` ON `vendors`.`userid` = `events_todo`.`vendor` WHERE (`vendors`.`city` LIKE '%%' AND `vendors`.`state` LIKE '%%' AND `vendors`.`country` LIKE '%%') AND events_todo.status IS NOT NULL
I am getting a Count of 0 for Status seems like the sum is not working properly. Please suggest what needs to be done.
You could go with a simple query like this
SELECT v.id, v.user_id, v.address, v.country, e.events_id, e.status, IF(e.status = 'Completed', 1, 0) AS count
FROM vendors AS v
LEFT JOIN events_todo AS e ON e.vendor = v.user_id
Output
id
user_id
address
country
events_id
status
count
1
10
NY
US
1
Completed
1
2
20
Mumbai
INDIA
2
Inprogress
0
Related
This is a simple query that when executed updates the cash available by some users when their loans are due:
$sqlx = "UPDATE competitions
SET cash = (SELECT cash_after_deduct
FROM (SELECT l.competitions_id,
(c.cash-l.due_amount) AS cash_after_deduct
FROM loans l
JOIN competitions c ON l.competitions_id = c.id
WHERE l.due_date='2018-10-28'
GROUP BY l.competitions_id) q1
WHERE q1.competitions_id = competitions.id
)
";
The cash row of those users with a loan due on 2018-10-28 should be modified. And it works; however the cash row in users with different due dates are reset to 0, while they should remain unaffected.
Any idea on what can be wrong?
Many thanks in advance.
Your UPDATE query has no criteria to limit the scope of the update to only those affected by the due_date.
Additionally since you are not using an aggregate function on the loans table, MySQL is free to choose ANY single value from those that were grouped. This can lead to unexpected results.
To resolve the issue you can change the SET subquery to a JOIN. This will prevent unmatched records from the loans table from updating the competitions table with 0's. As well as reduce the number of queries that would need to occur, since using a subquery in the SET would require a query to be issued for each record in order to match the current row in competitions that is being updated by set.
Example: http://sqlfiddle.com/#!9/2a2c147/1
UPDATE competitions AS c
INNER JOIN (
SELECT l.competitions_id, SUM(l.due_amount) AS total_due
FROM loans AS l
WHERE l.due_date = '2018-10-28'
GROUP BY l.competitions_id
#optionally limit scope to those that have an amount due
#HAVING total_due > 0
) AS d
ON d.competitions_id = c.id
SET c.cash = c.cash - d.total_due
Data Set
competitions
---
| id | cash |
|-----|------|
| 1 | 5.00 |
| 2 | 2.00 |
| 3 | 0.00 |
loans
---
| id | competitions_id | due_amount | due_date |
|----|-----------------|------------|------------|
| 1 | 1 | 1.00 | 2018-10-19 |
| 2 | 1 | 1.00 | 2018-10-28 |
| 3 | 2 | 1.00 | 2018-10-28 |
| 4 | 1 | 1.00 | 2018-10-28 |
| 5 | 3 | 1.00 | 2018-11-19 |
Result
| id | cash | total_due | cash_after_deduction | loan_deductions |
|----|------|-----------|----------------------|-----------------|
| 1 | 5 | 2 | 3 | 2 |
| 2 | 2 | 1 | 1 | 1 |
This works by first retrieving the competitions_id and due_amount values from the loans table that are affected by the due_date.
The base competitions table updates are then limited by the INNER JOIN, which includes only the records that match those found within the loans table.
I used SUM as the aggregate function to ensure all of the due_amount records from all the loans for the competitions_id are totaled.
This looks like what you had intended, if not and you want a single due_amount, the query can be modified to match your desired results.
Products :
--------------------------------------------
| ID | Group | Name | Sold |
--------------------------------------------
| 1 | A | Dell | 0 |
--------------------------------------------
| 2 | A | Dell | 0 |
--------------------------------------------
| 3 | B | Dell | 1 |
--------------------------------------------
| 4 | B | Dell | 1 |
--------------------------------------------
| 5 | C | Dell | 0 |
--------------------------------------------
| 6 | C | Dell | 1 |
--------------------------------------------
Hi everyone, i have a table (products) stored in MySql with many records, for now i'm using this query SELECT * FROM products WHERE sold = 0, in results i get :
--------------------------------------------
| ID | Group | Name | Sold |
--------------------------------------------
| 1 | A | Dell | 0 |
--------------------------------------------
| 2 | A | Dell | 0 |
--------------------------------------------
| 5 | C | Dell | 0 |
--------------------------------------------
i want to get only one record from each group, so the results will be like :
--------------------------------------------
| ID | Group | Name | Sold |
--------------------------------------------
| 1 | A | Dell | 0 |
--------------------------------------------
| 5 | C | Dell | 0 |
--------------------------------------------
You could easily do this by using a distinct clause and removing the id column. If you want to keep the id column you need to specify how one would chose which id to keep.
select distinct
`group`
, name
, sold
from
products
where
sold = 0;
To keep the row with the smallest id (as your example shows) something along the lines of the example below would work.
select
id
, `group`
, name
, sold
from
products
where
sold = 0
and id = (
select
min(p.id)
from
products p
where
p.`group` = products.`group`
and p.sold = 0
);
First, change your field named Group to something like Group_Name. GROUP is a reserved keyword, and if it is not causing you problems now it probably will later.
Second, you should ask yourself what you are really after. The following query should generate your desired result. It adds an additional condition where the IDs that are returned are the lowest numbered ID in each group.
SELECT * FROM products
WHERE sold = 0
AND ID IN (SELECT MIN(ID) FROM products WHERE sold = 0 GROUP BY Group_Name)
Why do you want that, though? That is not a normal desired end state. You should ask yourself why you care about the ID. It looks like your goal is to figure out which products have not sold anything. In that case, I would recommend this instead:
SELECT DISTINCT Group_Name, Name
FROM products
WHERE sold = 0
ORDER BY Group_Name, Name
I found the solution by using the statement GROUP BY,
SELECT * FROM products WHERE sold = 0 GROUP BY group
in the results now, i get only one record for each group and the minimal id without adding any other statement, and in my real table i am using product_group instead of group because it's a reserved word.
Try this:
SELECT `ID`, `Group`, `Name`, `Sold` FROM products WHERE sold = 0 GROUP BY `Group`;
I want to join 4 tables to list all the values from a table those have the duration from last updated to current date is more that the duration in other table, table are given below (my English not good to understand so am explaining with examble)
first table daily_tasks
+---------+---------+
| task_id | type_id |
+---------+---------+
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
+---------+---------+
Second Table daily_task_report
+-----------+---------+------------+
| report_id | task_id | task_date |
+-----------+---------+------------+
| 1 | 1 | 2015-09-10 |
| 2 | 3 | 2015-09-10 |
| 3 | 1 | 2015-09-11 |
| 4 | 3 | 2015-09-16 |
+-----------+---------+------------+
Third Table duration_types
+---------+---------------+------------------------+
| type_id | duration_type | duration_time(in days) |
+---------+---------------+------------------------+
| 1 | Daily Task | 1 |
| 2 | Weekly Task | 6 |
| 3 | Monthly Task | 26 |
| 4 | Yearly Task | 313 |
+---------+---------------+------------------------+
Fourth Table calendar
+--------+------------+---------+
| cal_id | cal_date | holiday |
+--------+------------+---------+
| 1 | 2015-09-10 | 0 |
| 2 | 2015-09-11 | 0 |
| 3 | 2015-09-12 | 0 |
| 4 | 2015-09-13 | 1 |
+--------+------------+---------+
Here daily_tasks.type_id is from duration_types.type_id and daily_task_report.task_id is from daily_tasks.task_id. I want to select all the task_id those task_date and current_date difference will greater than duration_time, also while calculating the duration i have to avoid the dates those have holiday=1 from calendar.
I tried queries but not proper, i got the values without including the calendar table, but that not a good way, query is taking more time to execute.
"SELECT dailyTasks.task_id FROM
(SELECT tab.* FROM (SELECT
tasks.task_type,report.*
FROM daily_tasks AS tasks
LEFT JOIN daily_task_reports AS report ON tasks.task_id=report.task_id
WHERE 1 ORDER BY report.task_date DESC) as tab GROUP BY tab.d_task_id) AS dailyTasks
LEFT JOIN duration_types AS type ON dailyTasks.task_type=type.type_id
WHERE DATEDIFF(CURDATE(),dailyTasks.task_date)>=type.duration_time"
Please someone help, I stuck in this section
According to given table You have some unexpected text or unknown columns in your query
Try this query
"SELECT dailyTasks.d_task_id FROM
(SELECT tab.* FROM
(SELECT tasks.type_id,report.* FROM daily_tasks AS tasks
LEFT JOIN daily_task_reports AS report ON tasks.task_id=report.task_id
ORDER BY report.task_date DESC)
as tab GROUP BY tab.task_id) AS dailyTasks
LEFT JOIN duration_types AS type ON dailyTasks.type_id=type.type_id
WHERE DATEDIFF(CURDATE(),dailyTasks.task_date)>=type.duration_time"
It can be also works in single query
SELECT tasks.task_id FROM daily_tasks AS tasks
LEFT JOIN daily_task_reports AS report ON tasks.task_id=report.task_id
LEFT JOIN duration_types AS type ON tasks.type_id = type.type_id and DATEDIFF(CURDATE(),report.task_date) >= type.duration_time
*I tried but not exclude that id which have holiday in calendar
You can create it on your coding side I gave you new query included with calendar
*
SELECT tasks.task_id,report.task_date,calendar.holiday FROM daily_tasks AS tasks
LEFT JOIN daily_task_reports AS report ON tasks.task_id=report.task_id
LEFT JOIN duration_types AS type ON tasks.type_id = type.type_id and DATEDIFF(CURDATE(),report.task_date) >= type.duration_time
LEFT JOIN calendar ON report.task_date=calendar.cal_date
where calendar.holiday = '0'
order By report.task_date desc
i have this problem with me on how to sum total value from two different table and then after getting its total i want to subtract it. for example i have table "rsales" and "sales" and i have these ff vlue below.
data from "rsales"
id | total | pcode |
1 | 100 | 2143 |
2 | 100 | 2143 |
3 | 50 | 2222 |
4 | 50 | 2222 |
data from "sales"
id | total | pcode |
7 | 100 | 2143 |
8 | 50 | 2222 |
my problem is this. i want to sum all "total" values from sales and sum "total"value from rsales group by pcode.and then after getting its sum i want to subtract it. my page must be something like this.
total pcode
| 100 | 2143 |
| 50 | 2222 |
i have this ff code but it doesnt wor for me
sql "select sum(rsales.total)- sum(sales.total) as t1 where pcode = rsales.pcode"
Use:
SELECT
SUM(r.total)-(
SELECT SUM(s.total)
FROM sales AS s WHERE r.pcode=s.pcode
) as total,
r.pcode
FROM rsales AS r
GROUP BY r.pcode;
Output:
+--+--+--+--+--+-
| total | pcode |
+--+--+--+--+--+-
| 100 | 2143 |
| 50 | 2222 |
+--+--+--+--+--+-
2 rows in set
Have you tried something like this?
SELECT
SUM(L.total) as lTotal, SUM(R.total) as rTotal
FROM
sales L
INNER JOIN rsales R
ON
R.pcode = L.pcode
GROUP BY L.pcode
If you get expected values from both tables you can easily add Additions and Subtruction in FROM clause.
There's no joins needed to do this. This solution works if some pcodes are only in one table:
select SUM(total), pcode from (
select sum(total) as total, pcode from rsales group by pcode
union all
select SUM(-total) as total, pcode from sales group by pcode) salesTables
group by pcode
I have two tables one that contains a huge list of items and another that trading for those items.
Here are examples tables:
The main table
| ID | TITLE | STATUS | TRADE |
-------------------------------
| 1 | test1 | 1 | 1 |
| 2 | test2 | 1 | 1 |
| 3 | test3 | 1 | 0 |
| 4 | test4 | 0 | 1 |
The trade table
| ID | TRADER | ITEM | URL |
------------------------------------------------------
| 1 | 2 | 1 | HTTP://www.test.com/itemOne |
| 2 | 5 | 3 | HTTP://www.test.com/itemThree |
| 3 | 5 | 4 | HTTP://www.test.com/itemFour |
Say I want to have a list of all the items that are not being traded by trader 5 and have a status of 1. So when trader 5 comes to the site they will be able to select the remaining items to trade.
Here is what I have tried:
$sql = "SELECT m.id, m.title
FROM main AS m, trade AS t
WHERE m.trade >= 1 && m.status = 1 &&
t.trader <>". mysql_real_escape_string($traderID);
This code just doesn't work. Any ideas on this?
It is not clear to me what column in Trades is an FK to Main. Below, I have assumed it is the Item column:
select m.id, m.title
from Main m
where not exists (
select *
from trade
where m.id = item
and trader = 5
)
and m.status = 1
Try this:
SELECT id, title FROM main
WHERE status = 1 AND id NOT IN
(SELECT item FROM trade WHERE trader = 5);
This will grab a list of every title in main with a status of 1, but limit the items based on a subquery which gets a list of ids already traded by trader 5 (i.e. items "not in" the list of items returned as having been traded by trader 5).
I'll leave it to you to update the query to be parameterized as needed.
Note that I'm assuming that item in trade is a foreign key to the id field in main, since you didn't specify it.