PDO Query : Count related and repeated values then inner join - php

I work with PHP and PDO.
So I have 2 tables like,
Table 1
| id | name | age |
| 1 | John | 25 |
| 2 | Tom | 32 |
| 3 | James| 45 |
Table 2
| id | Comment | Link |
| 1 | some text | 3 |
| 2 | some text | 3 |
| 3 | some text | 1 |
So, Link column numbers represent id's in table1. For example Link = 3s in table 2 represent James in table 1. I need a query which brings all table1's data and also a number of repeated value for related Link column which comes from table2.
For example, the query should give me (let's choose James),
| id | name | age | Value |
| 3 | James | 45 | 2 |
value=2, because there are two 3s in link column which related to James
I tried somethings but got lots of errors.

I think you just need the GROUP BY
SELECT a.id,
a.name,
a.age,
count(*) as value
FROM table1 a
JOIN table2 b ON a.id = b.link
GROUP BY a.id, a.name, a.age
If you really want just one row then add WHERE
SELECT a.id,
a.name,
a.age,
count(*) as value
FROM table1 a
JOIN table2 b ON a.id = b.link
WHERE a.name = 'James'
GROUP BY a.id, a.name, a.age
or use subquery
SELECT a.id,
a.name,
a.age,
(SELECT count(*) FROM table2 b WHERE a.id = b.link) as value
FROM table1 a
WHERE a.name = 'James'

Related

Sum of column is not working in join table PHP

I am trying to calculate the req_qty and in_qty from table1 and table2.
I am trying to fetch the joined 3 tables data SUM(req_qty), SUM(in_qty). Issue come if req.qty not save in table2 it will not works. I am left joining the table by this sku's ids
I made here a very simple table for calculating the sum of the column. generally, the sum of the column is multiplying the total rows.
Please don't close the post and guild for other thread. for my doubt clear i made here a table which I can understand. please help.
table1
ID | sku_1 | req_qty | trans_id
----------------------------------
1 | 123 | 150 | 12345
2 | 142 | 200 | 256314
3 | 123 | 100 | 896523
table2
ID | sku_2 | in_qty | trans_key
-----------------------------------
1 | 142 | 50 | 002563
table3
ID | sku_code | sku_name
--------------------------
1 | 142 | ABC
2 | 123 | XYZ
Expected Output
ID | sku | sku_name | reqQty | inQty
------------------------------------
1 | 123 | XYZ | 250 | 0
2 | 142 | ABC | 200 | 50
Edit to select data when table1 and table2 are empty
SELECT table1.id, table3.sku_code as sku, table3.sku_name,
sum(table1.req_qty) as reqQty, sum(table2.in_qty) as inQty
FROM table3
LEFT JOIN table1 on table3.sku_code = table1.sku_1
LEFT JOIN table2 on table3.sku_code = table2.sku_2
GROUP BY table1.id, table3.sku_code, table3.sku_name
Explanation
You can see an explanation on how left join works here https://www.w3schools.com/sql/sql_join_left.asp#:~:text=The%20LEFT%20JOIN%20keyword%20returns,if%20there%20is%20no%20match.
But to explain this query quickly, we will select all data from table3, left join will find all records from left table (here table3) and mathcing records from right tables (here table2 and table 1).

How do I select distinct rows and cross check in another table?

I have 3 tables, users and tasks and completed_tasks. So basically I want to select all tasks where the user_id = 2 AND also check that the task does not exist in another table` the So here is my tables:
users table:
+----+-------+
| id | name |
+----+-------+
| 1 | John |
| 2 | Sally |
+----+-------+
tasks table:
+----+-----------+---------+
| id | task_name | user_id |
+----+-----------+---------+
| 1 | mop floor | 2 |
| 2 | dishes | 1 |
| 3 | laundry | 2 |
| 4 | cook | 2 |
+----+-----------+---------+
completed_tasks table:
+----+---------+---------+
| id | task_id | user_id |
+----+---------+---------+
| 1 | 1 | 2 |
+----+---------+---------+
Here is my current SELECT code for my MySQL database:
$db = "SELECT DISTINCT tasks.task_name, users.name FROM tasks LEFT JOIN ON users.id = tasks.user_id WHERE tasks.user_id = 2";
THe problem I'm having is: I want it to search in completed_tasks table and if the task exists, then don't select that task.
I tried to do that by adding the following but it did not work:
LEFT JOIN completed_tasks ON completed_tasks.user_id = 2
That did not work because if I had multiple completed tasks, it would just ignore it all together.
I want the end result should return the user's name and task name of task 3 and 4.
Also, performance is critical in my application. I could use PHP and loop through the arrays and do SELECT for each of them but that would not be good for performance.
You have a few ways to do this.
You can use a LEFT JOIN and then check for NULL in the optional table.
SELECT a.name, b.task_name
FROM users a
JOIN tasks b ON a.id = b.user_id
LEFT JOIN completed_tasks c ON c.task_id = b.id AND c.user_id = b.user_id
WHERE c.id IS NULL
;
You can do a NOT EXISTS sub-query
SELECT a.name, b.task_name
FROM users a
JOIN tasks b ON a.id = b.user_id
WHERE NOT EXISTS (
SELECT 1
FROM completed_tasks c
WHERE c.task_id = b.id AND c.user_id = b.user_id)
;

SQL SELECT only rows having MAX value of a column from two different tables

My two table setup is like below:
table1
+------+---------+--------------------------------------+
| id | tail | content |
+------+---------+--------------------------------------+
| 1 | abc | ... |
| 2 | def | ... |
| 3 | ghi | ... |
| 4 | def | ... |
| 5 | jkl | ... |
+------+-------+----------------------------------------+
table2
+------+--------+---------------------------------------+
| id | tailID | value | others |
+------+--------+---------------------------------------+
| 1 | 2 | 412 | |
| 2 | 3 | 215 | |
| 1 | 2 | 571 | |
| 1 | 4 | 123 | |
+------+--------+---------------------------------------+
I like to get all columns from this two tables in a row with matched tail = tailID but not duplicate rows which has same tail.
For the duplicate TAIL, just need to get the single row of max VALUE of same tail.
I am currently using
SELECT table1.tail, table2.other_column
FROM table1
INNER JOIN table2
on table1.id = table2.tailID
WHERE table1.some_coloum = "a sepecific string"
ORDER BY table2.value
But it returns many duplicates of same tail.
I just need to have single row for duplicate TAIL with hightes VALUE of table2.
DISTINCT with CROSS APPLY:
SELECT DISTINCT t1.tail,
t2.other_column,
t3.[value]
FROM table1 t1
CROSS APPLY (
SELECT tailid,
MAX([value]) as [value]
FROM table2
WHERE tailid = t1.id
GROUP BY tailid
) as t3
INNER JOIN table2 t2
ON t2.tailid = t3.tailid AND t3.[value] = t2.[value]
WHERE t1.some_coloum = "a sepecific string"
First group table2 then join
SELECT table1.tail, table2.other_column
FROM table1
INNER JOIN (
SELECT tailID, max(value) as value
FROM table2
GROUP BY tailID
) t2g ON t2g.tailID = table1.ID
INNER JOIN table2
on t2g.tailID = table2.tailID AND t2g.value = table2.value
WHERE table1.some_coloum = "a sepecific string"
ORDER BY table2.value
The query still may return multiple rows for a table1 row if there are 2 or more rows in table2 with the same max(value) and tailID.
Selected only rows where is MAX value of column value
SELECT table1.tail, MAX(table2.value)
FROM
table1
INNER JOIN table2 ON table1.id = table2.tailID
WHERE table1.content = "test"
http://sqlfiddle.com/#!9/b70d29/3/0

MYSQL statement: lookup how many records exist how many times in other table

I have 2 database tables:
Table 1:
+---------+-------+-------------+
| Page | Title | Description |
+---------+-------+-------------+
| Apple | ..... | ........... |
| Orange | ..... | ........... |
| Pear | ..... | ........... |
| Grapes | ..... | ........... |
+---------+-------+-------------+
Table 2:
+----------+-------------+
| Link | Page |
+----------+-------------+
| Website1 | Apple |
| Website2 | Orange |
| Website3 | Apple |
| Website4 | Orange |
| Website5 | Apple |
| Website6 | Pear |
| Website7 | Apple |
| Website8 | Grapes |
| Website9 | Grapes |
+----------+-------------+
I want to know/return how many pages from Table 1 are referenced in Table 2 and how many times they are referenced. (I DON'T want to know how many times EACH page in Table 1 is referenced in Table 2).
So in this example:
1 page is referenced 1 time (Pear),
2 pages are referenced 2 times (Grapes and Orange) &
1 page is referenced 4 times.
What kind of SQL statement would I use to get this?
Following query should do..
SELECT COUNT(1) NoOfPages,CNT ReferencedTimes
FROM
(
SELECT T2.PAGE,COUNT(1) CNT
FROM TABLE1 T1 INNER JOIN TABLE2 T2 ON T1.PAGE = T2.PAGE
GROUP BY T2.PAGE
)T
GROUP BY CNT
I think the following statement will fit:
SELECT count(*) FROM Table2 WHERE (Table2.Page IN (SELECT Page FROM Table1));
Use This query
Select table2.page,cnt(table2.page)
from table1 inner join table2
On table1.Page=table2.Page group by table2.page
SELECT (GROUP_CONCAT(DISTINCT page)) AS Page,page_count
FROM
(SELECT table1.Page as page,COUNT(*) as page_count
FROM table1 INNER JOIN table2 ON table1.Page=table2.Page
GROUP BY table1.Page)
as T GROUP BY page_count
Hope this helps
If what you are seeking is X page was referenced N times, the below query will achieve that:
SELECT COUNT(t1.page), t2.count
FROM table1 t1
INNER JOIN (SELECT page,COUNT(*) AS count FROM table2 GROUP BY page) t2 ON t1.page=t2.page
GROUP BY t2.count
Try this query, it will make a left join and tell you how many times item is referenced in table2, if count is zero than no reference in the other table
SELECT table1.Page, count(table2.Page) as count
FROM table1
LEFT JOIN table2 ON table2.Page = table1.Page
GROUP BY table1.Page

mysql query to get all reviews for every company

I have a database with tables like below:
Reviews
id | review | companyid
companies
id | name
Now i want to get the data back so that i can show each company name with the total number of reviews for the company. Like seen below:
company 1 (company name) | 345
company 2 (company name) | 28
company 3 (company name) | 794
From here i will make a table using php to display the results
How can i achieve this with MYSQl?
Try this way:
SELECT Count(`r`.`review`) AS `total_reviews`,
`c`.`company`
FROM `reviews` AS `r`
JOIN `companies` AS `c`
ON `c`.`id` = `r`.`companyid`
Use COUNT and GROUP BY to count the reviews per company and use JOIN to get the company name from the other table.
Query
select t2.name as companyName,coalesce(t1.`count`,0) as `count` from
(
select companyid,count(companyid) as `count`
from reviews
group by companyid
)t1
right join companies t2
on t1.companyid= t2.id;
Sample Output
Table - reviews
+----+--------+-----------+
| id | review | companyid |
+----+--------+-----------+
| 1 | r1 | 1 |
| 2 | r2 | 2 |
| 3 | r3 | 1 |
+----+--------+-----------+
Table - companies
+----+------+
| id | name |
+----+------+
| 1 | C1 |
| 2 | C2 |
| 3 | C3 |
+----+------+
Output
+------+-------+
| name | count |
+------+-------+
| C1 | 2 |
| C2 | 1 |
| C3 | 0 |
+------+-------+
SQL Fiddle
You need to use a GROUP BY
SELECT r.companyid, c.name, count(r.id) as nb_review
FROM reviews r
INNER JOIN companies c ON (r.companyid = c.id)
GROUP BY r.companyid, c.name;
If you also want to see the companies with no reviews, do :
SELECT c.id, c.name, count(r.id) as nb_review
FROM companies c
LEFT JOIN reviews r ON (r.companyid = c.id)
GROUP BY c.id, c.name;

Categories